Compare commits
90 Commits
qemu-1.5.1
...
opensuse-1
Author | SHA1 | Date | |
---|---|---|---|
|
43526150fa | ||
|
9c1b799236 | ||
|
4f9265c707 | ||
|
9a860d428d | ||
|
a6664afab4 | ||
|
0a9d9af253 | ||
|
69a6177e05 | ||
|
e142d9e8ba | ||
|
cd606a8480 | ||
|
62783a25ef | ||
|
e9c0b65bbf | ||
|
1c1448c933 | ||
|
0f79964039 | ||
|
1e747ef08a | ||
|
351142c287 | ||
|
f0fd80de8f | ||
|
e8171f6d12 | ||
|
9a72708a58 | ||
|
c81d269280 | ||
|
8954d20f70 | ||
|
853112747f | ||
|
a4f0bf51a1 | ||
|
e8b8530dd8 | ||
|
dbaddb35cf | ||
|
c376a21e31 | ||
|
04b073cd49 | ||
|
dca5711f3a | ||
|
a2ccdcc82f | ||
|
c73ada0bb8 | ||
|
58ab3b92c4 | ||
|
361d891716 | ||
|
5808e2a356 | ||
|
dafb3a450b | ||
|
68c582bd8f | ||
|
1021c91ed3 | ||
|
8132af0065 | ||
|
b2e7230192 | ||
|
4c1134246f | ||
|
e093a96fb6 | ||
|
1e34dbb17e | ||
|
d9e44fedae | ||
|
e300580980 | ||
|
c2c3a70745 | ||
|
f48d5facfb | ||
|
53bd82c12d | ||
|
ddbcc8e3bf | ||
|
a28f243a16 | ||
|
a1508f4416 | ||
|
e968f21ceb | ||
|
7c38fac0f5 | ||
|
46def18ae5 | ||
|
3ffb4001c2 | ||
|
86a8d63bc1 | ||
|
102dd9167c | ||
|
d0ed2d2e8e | ||
|
d194ba1cdb | ||
|
8a0a9cf35b | ||
|
d928541b51 | ||
|
7a6d80e93c | ||
|
447a3b3473 | ||
|
e295c31e25 | ||
|
adf6c527b0 | ||
|
57ee5f77c0 | ||
|
986626efec | ||
|
85a4ca797d | ||
|
e47c212cb5 | ||
|
8afe984ef7 | ||
|
5bb37d151b | ||
|
fe5c13ebf1 | ||
|
6061f16a8a | ||
|
fbcf305e5a | ||
|
37769d2727 | ||
|
23201c64a7 | ||
|
c936f649d4 | ||
|
f63d074313 | ||
|
9b81fbdbb0 | ||
|
7e2191ae98 | ||
|
a25808dc5b | ||
|
3e8088148b | ||
|
6d450bfbc8 | ||
|
abf80f8804 | ||
|
3d3ec7b809 | ||
|
45d6cdff48 | ||
|
ed6857bf98 | ||
|
64dd41bc2d | ||
|
c554919f74 | ||
|
77a0262181 | ||
|
f03969b952 | ||
|
2061800b85 | ||
|
0b23c5d40e |
@@ -46,6 +46,7 @@ net-obj-y = net.o
|
||||
net-nested-y = queue.o checksum.o util.o
|
||||
net-nested-y += socket.o
|
||||
net-nested-y += dump.o
|
||||
net-nested-y += udp.o
|
||||
net-nested-$(CONFIG_POSIX) += tap.o
|
||||
net-nested-$(CONFIG_LINUX) += tap-linux.o
|
||||
net-nested-$(CONFIG_WIN32) += tap-win32.o
|
||||
@@ -310,8 +311,8 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-synth.o
|
||||
9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o
|
||||
9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o
|
||||
|
||||
hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
|
||||
$(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
|
||||
|
@@ -33,6 +33,10 @@ endif
|
||||
PROGS=$(QEMU_PROG)
|
||||
STPFILES=
|
||||
|
||||
ifdef CONFIG_LINUX_USER
|
||||
PROGS+=$(QEMU_PROG)-binfmt
|
||||
endif
|
||||
|
||||
ifndef CONFIG_HAIKU
|
||||
LIBS+=-lm
|
||||
endif
|
||||
@@ -139,6 +143,8 @@ obj-y += $(addprefix ../libuser/, $(user-obj-y))
|
||||
obj-y += $(addprefix ../libdis-user/, $(libdis-y))
|
||||
obj-y += $(libobj-y)
|
||||
|
||||
obj-binfmt-y += binfmt.o
|
||||
|
||||
endif #CONFIG_LINUX_USER
|
||||
|
||||
#########################################################
|
||||
@@ -416,6 +422,8 @@ obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
|
||||
$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
|
||||
$(call LINK,$^)
|
||||
|
||||
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
|
||||
$(call LINK,$^)
|
||||
|
||||
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
|
||||
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
|
||||
|
5
block.c
5
block.c
@@ -3151,7 +3151,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
||||
char *options, uint64_t img_size, int flags)
|
||||
{
|
||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
||||
QEMUOptionParameter *backing_fmt, *backing_file, *size;
|
||||
QEMUOptionParameter *backing_fmt, *backing_file, *size, *scsi;
|
||||
BlockDriverState *bs = NULL;
|
||||
BlockDriver *drv, *proto_drv;
|
||||
BlockDriver *backing_drv = NULL;
|
||||
@@ -3261,6 +3261,9 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
||||
|
||||
printf("Formatting '%s', fmt=%s ", filename, fmt);
|
||||
print_option_parameters(param);
|
||||
scsi = get_option_parameter(param, BLOCK_OPT_SCSI);
|
||||
if (scsi && scsi->value.n)
|
||||
printf(", SCSI");
|
||||
puts("");
|
||||
|
||||
ret = bdrv_create(drv, filename, param);
|
||||
|
@@ -97,7 +97,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
if (!(flags & BDRV_O_CACHE_WB))
|
||||
overlapped |= FILE_FLAG_WRITE_THROUGH;
|
||||
s->hfile = CreateFile(filename, access_flags,
|
||||
FILE_SHARE_READ, NULL,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, overlapped, NULL);
|
||||
if (s->hfile == INVALID_HANDLE_VALUE) {
|
||||
int err = GetLastError();
|
||||
@@ -387,7 +387,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
if (!(flags & BDRV_O_CACHE_WB))
|
||||
overlapped |= FILE_FLAG_WRITE_THROUGH;
|
||||
s->hfile = CreateFile(filename, access_flags,
|
||||
FILE_SHARE_READ, NULL,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
create_flags, overlapped, NULL);
|
||||
if (s->hfile == INVALID_HANDLE_VALUE) {
|
||||
int err = GetLastError();
|
||||
|
@@ -808,7 +808,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
|
||||
} while (snap_count == -ERANGE);
|
||||
|
||||
if (snap_count <= 0) {
|
||||
return snap_count;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));
|
||||
@@ -827,6 +827,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
|
||||
}
|
||||
rbd_snap_list_end(snaps);
|
||||
|
||||
done:
|
||||
*psn_tab = sn_tab;
|
||||
return snap_count;
|
||||
}
|
||||
|
12
block/vmdk.c
12
block/vmdk.c
@@ -1375,7 +1375,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
|
||||
"ddb.geometry.heads = \"16\"\n"
|
||||
"ddb.geometry.sectors = \"63\"\n"
|
||||
"ddb.adapterType = \"ide\"\n";
|
||||
"ddb.adapterType = \"%s\"\n";
|
||||
|
||||
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
|
||||
return -EINVAL;
|
||||
@@ -1390,6 +1390,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
|
||||
fmt = options->value.s;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_SCSI)) {
|
||||
flags |= options->value.n ? BLOCK_FLAG_SCSI: 0;
|
||||
}
|
||||
options++;
|
||||
}
|
||||
@@ -1480,7 +1482,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
parent_desc_line,
|
||||
ext_desc_lines,
|
||||
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
total_size / (int64_t)(63 * 16 * 512));
|
||||
total_size / (int64_t)(63 * 16 * 512),
|
||||
flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
|
||||
if (split || flat) {
|
||||
fd = open(
|
||||
filename,
|
||||
@@ -1583,6 +1586,11 @@ static QEMUOptionParameter vmdk_create_options[] = {
|
||||
"VMDK flat extent format, can be one of "
|
||||
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
|
||||
},
|
||||
{
|
||||
.name = BLOCK_OPT_SCSI,
|
||||
.type = OPT_FLAG,
|
||||
.help = "SCSI image"
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@@ -33,10 +33,12 @@
|
||||
|
||||
#define BLOCK_FLAG_ENCRYPT 1
|
||||
#define BLOCK_FLAG_COMPAT6 4
|
||||
#define BLOCK_FLAG_SCSI 8
|
||||
|
||||
#define BLOCK_OPT_SIZE "size"
|
||||
#define BLOCK_OPT_ENCRYPT "encryption"
|
||||
#define BLOCK_OPT_COMPAT6 "compat6"
|
||||
#define BLOCK_OPT_SCSI "scsi"
|
||||
#define BLOCK_OPT_BACKING_FILE "backing_file"
|
||||
#define BLOCK_OPT_BACKING_FMT "backing_fmt"
|
||||
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
|
||||
|
4
configure
vendored
4
configure
vendored
@@ -915,6 +915,8 @@ microblaze-linux-user \
|
||||
microblazeel-linux-user \
|
||||
mips-linux-user \
|
||||
mipsel-linux-user \
|
||||
mipsn32-linux-user \
|
||||
mipsn32el-linux-user \
|
||||
ppc-linux-user \
|
||||
ppc64-linux-user \
|
||||
ppc64abi32-linux-user \
|
||||
@@ -1116,7 +1118,7 @@ fi
|
||||
|
||||
if test "$pie" = ""; then
|
||||
case "$cpu-$targetos" in
|
||||
i386-Linux|x86_64-Linux)
|
||||
i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD)
|
||||
;;
|
||||
*)
|
||||
pie="no"
|
||||
|
@@ -186,7 +186,9 @@ void vga_hw_screen_dump(const char *filename)
|
||||
consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
|
||||
}
|
||||
|
||||
console_select(previous_active_console->index);
|
||||
if (previous_active_console) {
|
||||
console_select(previous_active_console->index);
|
||||
}
|
||||
}
|
||||
|
||||
void vga_hw_text_update(console_ch_t *chardata)
|
||||
|
@@ -35,6 +35,10 @@ enum {
|
||||
POOL_MAX_SIZE = 64,
|
||||
};
|
||||
|
||||
/** Free list to speed up creation */
|
||||
static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool);
|
||||
static unsigned int pool_size;
|
||||
|
||||
typedef struct {
|
||||
Coroutine base;
|
||||
void *stack;
|
||||
@@ -48,10 +52,6 @@ typedef struct {
|
||||
/** Currently executing coroutine */
|
||||
Coroutine *current;
|
||||
|
||||
/** Free list to speed up creation */
|
||||
QLIST_HEAD(, Coroutine) pool;
|
||||
unsigned int pool_size;
|
||||
|
||||
/** The default coroutine */
|
||||
CoroutineUContext leader;
|
||||
} CoroutineThreadState;
|
||||
@@ -75,7 +75,6 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
|
||||
if (!s) {
|
||||
s = g_malloc0(sizeof(*s));
|
||||
s->current = &s->leader.base;
|
||||
QLIST_INIT(&s->pool);
|
||||
pthread_setspecific(thread_state_key, s);
|
||||
}
|
||||
return s;
|
||||
@@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
|
||||
static void qemu_coroutine_thread_cleanup(void *opaque)
|
||||
{
|
||||
CoroutineThreadState *s = opaque;
|
||||
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void __attribute__((destructor)) coroutine_cleanup(void)
|
||||
{
|
||||
Coroutine *co;
|
||||
Coroutine *tmp;
|
||||
|
||||
QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
|
||||
QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
|
||||
g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
|
||||
g_free(co);
|
||||
}
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) coroutine_init(void)
|
||||
@@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void)
|
||||
|
||||
Coroutine *qemu_coroutine_new(void)
|
||||
{
|
||||
CoroutineThreadState *s = coroutine_get_thread_state();
|
||||
Coroutine *co;
|
||||
|
||||
co = QLIST_FIRST(&s->pool);
|
||||
co = QLIST_FIRST(&pool);
|
||||
if (co) {
|
||||
QLIST_REMOVE(co, pool_next);
|
||||
s->pool_size--;
|
||||
pool_size--;
|
||||
} else {
|
||||
co = coroutine_new();
|
||||
}
|
||||
@@ -184,13 +187,12 @@ Coroutine *qemu_coroutine_new(void)
|
||||
|
||||
void qemu_coroutine_delete(Coroutine *co_)
|
||||
{
|
||||
CoroutineThreadState *s = coroutine_get_thread_state();
|
||||
CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
|
||||
|
||||
if (s->pool_size < POOL_MAX_SIZE) {
|
||||
QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next);
|
||||
if (pool_size < POOL_MAX_SIZE) {
|
||||
QLIST_INSERT_HEAD(&pool, &co->base, pool_next);
|
||||
co->base.caller = NULL;
|
||||
s->pool_size++;
|
||||
pool_size++;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -204,7 +204,8 @@ extern unsigned long reserved_va;
|
||||
#else
|
||||
#define h2g_valid(x) ({ \
|
||||
unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
|
||||
__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
|
||||
(__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \
|
||||
(!RESERVED_VA || (__guest < RESERVED_VA)); \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
@@ -172,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
|
||||
#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
|
||||
#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
|
||||
#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT)
|
||||
#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
|
||||
|
||||
/* Acts like a ROM when read and like a device when written. */
|
||||
#define IO_MEM_ROMD (1)
|
||||
|
11
cpu-exec.c
11
cpu-exec.c
@@ -564,7 +564,16 @@ int cpu_exec(CPUState *env)
|
||||
tc_ptr = tb->tc_ptr;
|
||||
/* execute the generated code */
|
||||
next_tb = tcg_qemu_tb_exec(env, tc_ptr);
|
||||
if ((next_tb & 3) == 2) {
|
||||
if ((next_tb & 3) == 3) {
|
||||
/* hit stopflag check */
|
||||
tb = (TranslationBlock *)(long)(next_tb & ~3);
|
||||
/* Restore PC. */
|
||||
cpu_pc_from_tb(env, tb);
|
||||
next_tb = 0;
|
||||
env->exit_request = 0;
|
||||
env->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit(env);
|
||||
} else if ((next_tb & 3) == 2) {
|
||||
/* Instruction counter expired. */
|
||||
int insns_left;
|
||||
tb = (TranslationBlock *)(long)(next_tb & ~3);
|
||||
|
3
cutils.c
3
cutils.c
@@ -217,7 +217,10 @@ void qemu_iovec_destroy(QEMUIOVector *qiov)
|
||||
{
|
||||
assert(qiov->nalloc != -1);
|
||||
|
||||
qemu_iovec_reset(qiov);
|
||||
g_free(qiov->iov);
|
||||
qiov->nalloc = 0;
|
||||
qiov->iov = NULL;
|
||||
}
|
||||
|
||||
void qemu_iovec_reset(QEMUIOVector *qiov)
|
||||
|
1
default-configs/mipsn32-linux-user.mak
Normal file
1
default-configs/mipsn32-linux-user.mak
Normal file
@@ -0,0 +1 @@
|
||||
# Default configuration for mips-linux-user
|
1
default-configs/mipsn32el-linux-user.mak
Normal file
1
default-configs/mipsn32el-linux-user.mak
Normal file
@@ -0,0 +1 @@
|
||||
# Default configuration for mipsel-linux-user
|
@@ -96,6 +96,8 @@ void QEMU_NORETURN cpu_loop_exit(CPUState *env1);
|
||||
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
|
||||
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
int is_cpu_write_access);
|
||||
void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
int is_cpu_write_access);
|
||||
void tlb_flush_page(CPUState *env, target_ulong addr);
|
||||
void tlb_flush(CPUState *env, int flush_global);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
98
exec.c
98
exec.c
@@ -125,6 +125,8 @@ DEFINE_TLS(CPUState *,cpu_single_env);
|
||||
1 = Precise instruction counting.
|
||||
2 = Adaptive rate instruction counting. */
|
||||
int use_icount = 0;
|
||||
/* 1 to do cpu_exit by inline flag check rather than tb link breaking */
|
||||
int use_stopflag = 1;
|
||||
|
||||
typedef struct PageDesc {
|
||||
/* list of TBs intersecting this ram page */
|
||||
@@ -1014,6 +1016,23 @@ TranslationBlock *tb_gen_code(CPUState *env,
|
||||
return tb;
|
||||
}
|
||||
|
||||
/*
|
||||
* invalidate all TBs which intersect with the target physical pages
|
||||
* starting in range [start;end[. NOTE: start and end may refer to
|
||||
* different physical pages. 'is_cpu_write_access' should be true if called
|
||||
* from a real cpu write access: the virtual CPU will exit the current
|
||||
* TB if code is modified inside this TB.
|
||||
*/
|
||||
void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
int is_cpu_write_access)
|
||||
{
|
||||
while (start < end) {
|
||||
tb_invalidate_phys_page_range(start, end, is_cpu_write_access);
|
||||
start &= TARGET_PAGE_MASK;
|
||||
start += TARGET_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* invalidate all TBs which intersect with the target physical page
|
||||
starting in range [start;end[. NOTE: start and end must refer to
|
||||
the same physical page. 'is_cpu_write_access' should be true if called
|
||||
@@ -1670,7 +1689,13 @@ static void tcg_handle_interrupt(CPUState *env, int mask)
|
||||
cpu_abort(env, "Raised interrupt while not in I/O function");
|
||||
}
|
||||
} else {
|
||||
cpu_unlink_tb(env);
|
||||
// XXX just call cpu_exit ?
|
||||
if (use_stopflag) {
|
||||
// XXX is this OK?
|
||||
env->exit_request = 1;
|
||||
} else {
|
||||
cpu_unlink_tb(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1693,7 +1718,9 @@ void cpu_reset_interrupt(CPUState *env, int mask)
|
||||
void cpu_exit(CPUState *env)
|
||||
{
|
||||
env->exit_request = 1;
|
||||
cpu_unlink_tb(env);
|
||||
if (!use_stopflag) {
|
||||
cpu_unlink_tb(env);
|
||||
}
|
||||
}
|
||||
|
||||
const CPULogItem cpu_log_items[] = {
|
||||
@@ -2821,10 +2848,12 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef TARGET_PPC
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
|
||||
return NULL;
|
||||
@@ -3570,6 +3599,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = {
|
||||
&subpage_writel,
|
||||
};
|
||||
|
||||
static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
return ldub_p(ptr);
|
||||
}
|
||||
|
||||
static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr,
|
||||
uint32_t value)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
stb_p(ptr, value);
|
||||
}
|
||||
|
||||
static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
return lduw_p(ptr);
|
||||
}
|
||||
|
||||
static void subpage_ram_writew(void *opaque, target_phys_addr_t addr,
|
||||
uint32_t value)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
stw_p(ptr, value);
|
||||
}
|
||||
|
||||
static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
return ldl_p(ptr);
|
||||
}
|
||||
|
||||
static void subpage_ram_writel(void *opaque, target_phys_addr_t addr,
|
||||
uint32_t value)
|
||||
{
|
||||
ram_addr_t raddr = addr;
|
||||
void *ptr = qemu_get_ram_ptr(raddr);
|
||||
stl_p(ptr, value);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const subpage_ram_read[] = {
|
||||
&subpage_ram_readb,
|
||||
&subpage_ram_readw,
|
||||
&subpage_ram_readl,
|
||||
};
|
||||
|
||||
static CPUWriteMemoryFunc * const subpage_ram_write[] = {
|
||||
&subpage_ram_writeb,
|
||||
&subpage_ram_writew,
|
||||
&subpage_ram_writel,
|
||||
};
|
||||
|
||||
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||
ram_addr_t memory, ram_addr_t region_offset)
|
||||
{
|
||||
@@ -3583,8 +3669,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||
printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
|
||||
mmio, start, end, idx, eidx, memory);
|
||||
#endif
|
||||
if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
|
||||
memory = IO_MEM_UNASSIGNED;
|
||||
if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
|
||||
memory = IO_MEM_SUBPAGE_RAM;
|
||||
}
|
||||
memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
|
||||
for (; idx <= eidx; idx++) {
|
||||
mmio->sub_io_index[idx] = memory;
|
||||
@@ -3817,6 +3904,9 @@ static void io_mem_init(void)
|
||||
cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
|
||||
notdirty_mem_write, NULL,
|
||||
DEVICE_NATIVE_ENDIAN);
|
||||
cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
|
||||
subpage_ram_write, NULL,
|
||||
DEVICE_NATIVE_ENDIAN);
|
||||
for (i=0; i<5; i++)
|
||||
io_mem_used[i] = 1;
|
||||
|
||||
|
@@ -74,7 +74,7 @@ typedef struct FsContext
|
||||
} FsContext;
|
||||
|
||||
typedef struct V9fsPath {
|
||||
int16_t size;
|
||||
uint16_t size;
|
||||
char *data;
|
||||
} V9fsPath;
|
||||
|
||||
@@ -112,10 +112,10 @@ typedef struct FileOperations
|
||||
ssize_t (*pwritev)(FsContext *, V9fsFidOpenState *,
|
||||
const struct iovec *, int, off_t);
|
||||
int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *);
|
||||
int (*fstat)(FsContext *, V9fsFidOpenState *, struct stat *);
|
||||
int (*fstat)(FsContext *, int, V9fsFidOpenState *, struct stat *);
|
||||
int (*rename)(FsContext *, const char *, const char *);
|
||||
int (*truncate)(FsContext *, V9fsPath *, off_t);
|
||||
int (*fsync)(FsContext *, V9fsFidOpenState *, int);
|
||||
int (*fsync)(FsContext *, int, V9fsFidOpenState *, int);
|
||||
int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf);
|
||||
ssize_t (*lgetxattr)(FsContext *, V9fsPath *,
|
||||
const char *, void *, size_t);
|
||||
|
@@ -23,7 +23,9 @@ static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
|
||||
|
||||
static FsDriverTable FsDrivers[] = {
|
||||
{ .name = "local", .ops = &local_ops},
|
||||
#ifdef CONFIG_OPEN_BY_HANDLE
|
||||
{ .name = "handle", .ops = &handle_ops},
|
||||
#endif
|
||||
{ .name = "synth", .ops = &synth_ops},
|
||||
};
|
||||
|
||||
|
16
gen-icount.h
16
gen-icount.h
@@ -2,13 +2,25 @@
|
||||
|
||||
/* Helpers for instruction counting code generation. */
|
||||
|
||||
extern int use_stopflag;
|
||||
|
||||
static TCGArg *icount_arg;
|
||||
static int icount_label;
|
||||
static int stopflag_label;
|
||||
|
||||
static inline void gen_icount_start(void)
|
||||
{
|
||||
TCGv_i32 count;
|
||||
|
||||
if (use_stopflag) {
|
||||
TCGv_i32 flag;
|
||||
stopflag_label = gen_new_label();
|
||||
flag = tcg_temp_local_new_i32();
|
||||
tcg_gen_ld_i32(flag, cpu_env, offsetof(CPUState, exit_request));
|
||||
tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, stopflag_label);
|
||||
tcg_temp_free_i32(flag);
|
||||
}
|
||||
|
||||
if (!use_icount)
|
||||
return;
|
||||
|
||||
@@ -26,6 +38,10 @@ static inline void gen_icount_start(void)
|
||||
|
||||
static void gen_icount_end(TranslationBlock *tb, int num_insns)
|
||||
{
|
||||
if (use_stopflag) {
|
||||
gen_set_label(stopflag_label);
|
||||
tcg_gen_exit_tb((long)tb + 3); // XXX
|
||||
}
|
||||
if (use_icount) {
|
||||
*icount_arg = num_insns;
|
||||
gen_set_label(icount_label);
|
||||
|
@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
|
||||
}
|
||||
v9fs_co_run_in_worker(
|
||||
{
|
||||
err = s->ops->fstat(&s->ctx, &fidp->fs, stbuf);
|
||||
err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
|
||||
}
|
||||
v9fs_co_run_in_worker(
|
||||
{
|
||||
err = s->ops->fsync(&s->ctx, &fidp->fs, datasync);
|
||||
err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
}
|
||||
|
@@ -33,13 +33,15 @@ static V9fsState *to_virtio_9p(VirtIODevice *vdev)
|
||||
|
||||
static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
|
||||
{
|
||||
int len;
|
||||
struct virtio_9p_config *cfg;
|
||||
V9fsState *s = to_virtio_9p(vdev);
|
||||
|
||||
cfg = g_malloc0(sizeof(struct virtio_9p_config) +
|
||||
s->tag_len);
|
||||
stw_raw(&cfg->tag_len, s->tag_len);
|
||||
memcpy(cfg->tag, s->tag, s->tag_len);
|
||||
len = strlen(s->tag);
|
||||
cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
|
||||
stw_raw(&cfg->tag_len, len);
|
||||
/* We don't copy the terminating null to config space */
|
||||
memcpy(cfg->tag, s->tag, len);
|
||||
memcpy(config, cfg, s->config_size);
|
||||
g_free(cfg);
|
||||
}
|
||||
@@ -96,20 +98,18 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
|
||||
}
|
||||
|
||||
len = strlen(conf->tag);
|
||||
if (len > MAX_TAG_LEN) {
|
||||
if (len > MAX_TAG_LEN - 1) {
|
||||
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
|
||||
"maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN);
|
||||
"maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN - 1);
|
||||
exit(1);
|
||||
}
|
||||
/* s->tag is non-NULL terminated string */
|
||||
s->tag = g_malloc(len);
|
||||
memcpy(s->tag, conf->tag, len);
|
||||
s->tag_len = len;
|
||||
|
||||
s->tag = strdup(conf->tag);
|
||||
s->ctx.uid = -1;
|
||||
|
||||
s->ops = fse->ops;
|
||||
s->vdev.get_features = virtio_9p_get_features;
|
||||
s->config_size = sizeof(struct virtio_9p_config) + s->tag_len;
|
||||
s->config_size = sizeof(struct virtio_9p_config) + len;
|
||||
s->vdev.get_config = virtio_9p_get_config;
|
||||
s->fid_list = NULL;
|
||||
qemu_co_rwlock_init(&s->rename_lock);
|
||||
@@ -176,7 +176,8 @@ static PCIDeviceInfo virtio_9p_info = {
|
||||
DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
|
||||
DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
}
|
||||
},
|
||||
.qdev.reset = virtio_pci_reset,
|
||||
};
|
||||
|
||||
static void virtio_9p_register_devices(void)
|
||||
|
@@ -45,7 +45,6 @@ struct handle_data {
|
||||
int handle_bytes;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OPEN_BY_HANDLE
|
||||
static inline int name_to_handle(int dirfd, const char *name,
|
||||
struct file_handle *fh, int *mnt_id, int flags)
|
||||
{
|
||||
@@ -56,38 +55,6 @@ static inline int open_by_handle(int mountfd, const char *fh, int flags)
|
||||
{
|
||||
return open_by_handle_at(mountfd, (struct file_handle *)fh, flags);
|
||||
}
|
||||
#else
|
||||
|
||||
struct rpl_file_handle {
|
||||
unsigned int handle_bytes;
|
||||
int handle_type;
|
||||
unsigned char handle[0];
|
||||
};
|
||||
#define file_handle rpl_file_handle
|
||||
|
||||
#ifndef AT_REMOVEDIR
|
||||
#define AT_REMOVEDIR 0x200
|
||||
#endif
|
||||
#ifndef AT_EMPTY_PATH
|
||||
#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
|
||||
#endif
|
||||
#ifndef O_PATH
|
||||
#define O_PATH 010000000
|
||||
#endif
|
||||
|
||||
static inline int name_to_handle(int dirfd, const char *name,
|
||||
struct file_handle *fh, int *mnt_id, int flags)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int open_by_handle(int mountfd, const char *fh, int flags)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp)
|
||||
{
|
||||
@@ -288,10 +255,17 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int handle_fstat(FsContext *fs_ctx, V9fsFidOpenState *fs,
|
||||
struct stat *stbuf)
|
||||
static int handle_fstat(FsContext *fs_ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, struct stat *stbuf)
|
||||
{
|
||||
return fstat(fs->fd, stbuf);
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
return fstat(fd, stbuf);
|
||||
}
|
||||
|
||||
static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
||||
@@ -428,12 +402,21 @@ static int handle_remove(FsContext *ctx, const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
|
||||
static int handle_fsync(FsContext *ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, int datasync)
|
||||
{
|
||||
if (datasync) {
|
||||
return qemu_fdatasync(fs->fd);
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
} else {
|
||||
return fsync(fs->fd);
|
||||
fd = fs->fd;
|
||||
}
|
||||
|
||||
if (datasync) {
|
||||
return qemu_fdatasync(fd);
|
||||
} else {
|
||||
return fsync(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -366,11 +366,18 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int local_fstat(FsContext *fs_ctx,
|
||||
static int local_fstat(FsContext *fs_ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, struct stat *stbuf)
|
||||
{
|
||||
int err;
|
||||
err = fstat(fs->fd, stbuf);
|
||||
int err, fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
} else {
|
||||
fd = fs->fd;
|
||||
}
|
||||
|
||||
err = fstat(fd, stbuf);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -381,19 +388,19 @@ static int local_fstat(FsContext *fs_ctx,
|
||||
mode_t tmp_mode;
|
||||
dev_t tmp_dev;
|
||||
|
||||
if (fgetxattr(fs->fd, "user.virtfs.uid",
|
||||
if (fgetxattr(fd, "user.virtfs.uid",
|
||||
&tmp_uid, sizeof(uid_t)) > 0) {
|
||||
stbuf->st_uid = tmp_uid;
|
||||
}
|
||||
if (fgetxattr(fs->fd, "user.virtfs.gid",
|
||||
if (fgetxattr(fd, "user.virtfs.gid",
|
||||
&tmp_gid, sizeof(gid_t)) > 0) {
|
||||
stbuf->st_gid = tmp_gid;
|
||||
}
|
||||
if (fgetxattr(fs->fd, "user.virtfs.mode",
|
||||
if (fgetxattr(fd, "user.virtfs.mode",
|
||||
&tmp_mode, sizeof(mode_t)) > 0) {
|
||||
stbuf->st_mode = tmp_mode;
|
||||
}
|
||||
if (fgetxattr(fs->fd, "user.virtfs.rdev",
|
||||
if (fgetxattr(fd, "user.virtfs.rdev",
|
||||
&tmp_dev, sizeof(dev_t)) > 0) {
|
||||
stbuf->st_rdev = tmp_dev;
|
||||
}
|
||||
@@ -592,12 +599,21 @@ static int local_remove(FsContext *ctx, const char *path)
|
||||
return remove(rpath(ctx, path, buffer));
|
||||
}
|
||||
|
||||
static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
|
||||
static int local_fsync(FsContext *ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, int datasync)
|
||||
{
|
||||
if (datasync) {
|
||||
return qemu_fdatasync(fs->fd);
|
||||
int fd;
|
||||
|
||||
if (fid_type == P9_FID_DIR) {
|
||||
fd = dirfd(fs->dir);
|
||||
} else {
|
||||
return fsync(fs->fd);
|
||||
fd = fs->fd;
|
||||
}
|
||||
|
||||
if (datasync) {
|
||||
return qemu_fdatasync(fd);
|
||||
} else {
|
||||
return fsync(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -166,7 +166,7 @@ static int v9fs_synth_lstat(FsContext *fs_ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v9fs_synth_fstat(FsContext *fs_ctx,
|
||||
static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, struct stat *stbuf)
|
||||
{
|
||||
V9fsSynthOpenState *synth_open = fs->private;
|
||||
@@ -414,7 +414,8 @@ static int v9fs_synth_remove(FsContext *ctx, const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int v9fs_synth_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
|
||||
static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
|
||||
V9fsFidOpenState *fs, int datasync)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return 0;
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "virtio-9p-xattr.h"
|
||||
#include "virtio-9p-coth.h"
|
||||
#include "trace.h"
|
||||
#include "migration.h"
|
||||
|
||||
int open_fd_hw;
|
||||
int total_open_fd;
|
||||
@@ -373,6 +374,19 @@ static void put_fid(V9fsPDU *pdu, V9fsFidState *fidp)
|
||||
* Don't free the fid if it is in reclaim list
|
||||
*/
|
||||
if (!fidp->ref && fidp->clunked) {
|
||||
if (fidp->fid == pdu->s->root_fid) {
|
||||
/*
|
||||
* if the clunked fid is root fid then we
|
||||
* have unmounted the fs on the client side.
|
||||
* delete the migration blocker. Ideally, this
|
||||
* should be hooked to transport close notification
|
||||
*/
|
||||
if (pdu->s->migration_blocker) {
|
||||
migrate_del_blocker(pdu->s->migration_blocker);
|
||||
error_free(pdu->s->migration_blocker);
|
||||
pdu->s->migration_blocker = NULL;
|
||||
}
|
||||
}
|
||||
free_fid(pdu, fidp);
|
||||
}
|
||||
}
|
||||
@@ -509,6 +523,30 @@ static int v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void virtfs_reset(V9fsPDU *pdu)
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsFidState *fidp = NULL;
|
||||
|
||||
/* Free all fids */
|
||||
while (s->fid_list) {
|
||||
fidp = s->fid_list;
|
||||
s->fid_list = fidp->next;
|
||||
|
||||
if (fidp->ref) {
|
||||
fidp->clunked = 1;
|
||||
} else {
|
||||
free_fid(pdu, fidp);
|
||||
}
|
||||
}
|
||||
if (fidp) {
|
||||
/* One or more unclunked fids found... */
|
||||
error_report("9pfs:%s: One or more uncluncked fids "
|
||||
"found during reset", __func__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define P9_QID_TYPE_DIR 0x80
|
||||
#define P9_QID_TYPE_SYMLINK 0x02
|
||||
|
||||
@@ -636,40 +674,6 @@ static size_t pdu_pack(V9fsPDU *pdu, size_t offset, const void *src,
|
||||
offset, size, 1);
|
||||
}
|
||||
|
||||
static int pdu_copy_sg(V9fsPDU *pdu, size_t offset, int rx, struct iovec *sg)
|
||||
{
|
||||
size_t pos = 0;
|
||||
int i, j;
|
||||
struct iovec *src_sg;
|
||||
unsigned int num;
|
||||
|
||||
if (rx) {
|
||||
src_sg = pdu->elem.in_sg;
|
||||
num = pdu->elem.in_num;
|
||||
} else {
|
||||
src_sg = pdu->elem.out_sg;
|
||||
num = pdu->elem.out_num;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (offset <= pos) {
|
||||
sg[j].iov_base = src_sg[i].iov_base;
|
||||
sg[j].iov_len = src_sg[i].iov_len;
|
||||
j++;
|
||||
} else if (offset < (src_sg[i].iov_len + pos)) {
|
||||
sg[j].iov_base = src_sg[i].iov_base;
|
||||
sg[j].iov_len = src_sg[i].iov_len;
|
||||
sg[j].iov_base += (offset - pos);
|
||||
sg[j].iov_len -= (offset - pos);
|
||||
j++;
|
||||
}
|
||||
pos += src_sg[i].iov_len;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
|
||||
{
|
||||
size_t old_offset = offset;
|
||||
@@ -705,12 +709,6 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
|
||||
*valp = le64_to_cpu(val);
|
||||
break;
|
||||
}
|
||||
case 'v': {
|
||||
struct iovec *iov = va_arg(ap, struct iovec *);
|
||||
int *iovcnt = va_arg(ap, int *);
|
||||
*iovcnt = pdu_copy_sg(pdu, offset, 0, iov);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
V9fsString *str = va_arg(ap, V9fsString *);
|
||||
offset += pdu_unmarshal(pdu, offset, "w", &str->size);
|
||||
@@ -789,12 +787,6 @@ static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
|
||||
offset += pdu_pack(pdu, offset, &val, sizeof(val));
|
||||
break;
|
||||
}
|
||||
case 'v': {
|
||||
struct iovec *iov = va_arg(ap, struct iovec *);
|
||||
int *iovcnt = va_arg(ap, int *);
|
||||
*iovcnt = pdu_copy_sg(pdu, offset, 1, iov);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
V9fsString *str = va_arg(ap, V9fsString *);
|
||||
offset += pdu_marshal(pdu, offset, "w", str->size);
|
||||
@@ -1105,42 +1097,6 @@ static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf,
|
||||
stat_to_qid(stbuf, &v9lstat->qid);
|
||||
}
|
||||
|
||||
static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt)
|
||||
{
|
||||
while (len && *iovcnt) {
|
||||
if (len < sg->iov_len) {
|
||||
sg->iov_len -= len;
|
||||
sg->iov_base += len;
|
||||
len = 0;
|
||||
} else {
|
||||
len -= sg->iov_len;
|
||||
sg++;
|
||||
*iovcnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sg;
|
||||
}
|
||||
|
||||
static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt)
|
||||
{
|
||||
int i;
|
||||
int total = 0;
|
||||
|
||||
for (i = 0; i < *cnt; i++) {
|
||||
if ((total + sg[i].iov_len) > cap) {
|
||||
sg[i].iov_len -= ((total + sg[i].iov_len) - cap);
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
total += sg[i].iov_len;
|
||||
}
|
||||
|
||||
*cnt = i;
|
||||
|
||||
return sg;
|
||||
}
|
||||
|
||||
static void print_sg(struct iovec *sg, int cnt)
|
||||
{
|
||||
int i;
|
||||
@@ -1182,6 +1138,8 @@ static void v9fs_version(void *opaque)
|
||||
pdu_unmarshal(pdu, offset, "ds", &s->msize, &version);
|
||||
trace_v9fs_version(pdu->tag, pdu->id, s->msize, version.data);
|
||||
|
||||
virtfs_reset(pdu);
|
||||
|
||||
if (!strcmp(version.data, "9P2000.u")) {
|
||||
s->proto_version = V9FS_PROTO_2000U;
|
||||
} else if (!strcmp(version.data, "9P2000.L")) {
|
||||
@@ -1235,6 +1193,11 @@ static void v9fs_attach(void *opaque)
|
||||
err = offset;
|
||||
trace_v9fs_attach_return(pdu->tag, pdu->id,
|
||||
qid.type, qid.version, qid.path);
|
||||
s->root_fid = fid;
|
||||
/* disable migration */
|
||||
error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
|
||||
s->ctx.fs_root, s->tag);
|
||||
migrate_add_blocker(s->migration_blocker);
|
||||
out:
|
||||
put_fid(pdu, fidp);
|
||||
out_nofid:
|
||||
@@ -1731,8 +1694,8 @@ out_nofid:
|
||||
complete_pdu(s, pdu, err);
|
||||
}
|
||||
|
||||
static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
|
||||
V9fsFidState *fidp, int64_t off, int32_t max_count)
|
||||
static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
|
||||
uint64_t off, uint32_t max_count)
|
||||
{
|
||||
size_t offset = 7;
|
||||
int read_count;
|
||||
@@ -1756,7 +1719,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
|
||||
}
|
||||
|
||||
static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
|
||||
V9fsFidState *fidp, int32_t max_count)
|
||||
V9fsFidState *fidp, uint32_t max_count)
|
||||
{
|
||||
V9fsPath path;
|
||||
V9fsStat v9stat;
|
||||
@@ -1816,14 +1779,46 @@ out:
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a QEMUIOVector for a sub-region of PDU iovecs
|
||||
*
|
||||
* @qiov: uninitialized QEMUIOVector
|
||||
* @skip: number of bytes to skip from beginning of PDU
|
||||
* @size: number of bytes to include
|
||||
* @is_write: true - write, false - read
|
||||
*
|
||||
* The resulting QEMUIOVector has heap-allocated iovecs and must be cleaned up
|
||||
* with qemu_iovec_destroy().
|
||||
*/
|
||||
static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
|
||||
uint64_t skip, size_t size,
|
||||
bool is_write)
|
||||
{
|
||||
QEMUIOVector elem;
|
||||
struct iovec *iov;
|
||||
unsigned int niov;
|
||||
|
||||
if (is_write) {
|
||||
iov = pdu->elem.out_sg;
|
||||
niov = pdu->elem.out_num;
|
||||
} else {
|
||||
iov = pdu->elem.in_sg;
|
||||
niov = pdu->elem.in_num;
|
||||
}
|
||||
|
||||
qemu_iovec_init_external(&elem, iov, niov);
|
||||
qemu_iovec_init(qiov, niov);
|
||||
qemu_iovec_copy(qiov, &elem, skip, size);
|
||||
}
|
||||
|
||||
static void v9fs_read(void *opaque)
|
||||
{
|
||||
int32_t fid;
|
||||
int64_t off;
|
||||
uint64_t off;
|
||||
ssize_t err = 0;
|
||||
int32_t count = 0;
|
||||
size_t offset = 7;
|
||||
int32_t max_count;
|
||||
uint32_t max_count;
|
||||
V9fsFidState *fidp;
|
||||
V9fsPDU *pdu = opaque;
|
||||
V9fsState *s = pdu->s;
|
||||
@@ -1850,21 +1845,21 @@ static void v9fs_read(void *opaque)
|
||||
err += pdu_marshal(pdu, offset, "d", count);
|
||||
err += count;
|
||||
} else if (fidp->fid_type == P9_FID_FILE) {
|
||||
int32_t cnt;
|
||||
QEMUIOVector qiov_full;
|
||||
QEMUIOVector qiov;
|
||||
int32_t len;
|
||||
struct iovec *sg;
|
||||
struct iovec iov[128]; /* FIXME: bad, bad, bad */
|
||||
|
||||
sg = iov;
|
||||
pdu_marshal(pdu, offset + 4, "v", sg, &cnt);
|
||||
sg = cap_sg(sg, max_count, &cnt);
|
||||
v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, max_count, false);
|
||||
qemu_iovec_init(&qiov, qiov_full.niov);
|
||||
do {
|
||||
qemu_iovec_reset(&qiov);
|
||||
qemu_iovec_copy(&qiov, &qiov_full, count, qiov_full.size - count);
|
||||
if (0) {
|
||||
print_sg(sg, cnt);
|
||||
print_sg(qiov.iov, qiov.niov);
|
||||
}
|
||||
/* Loop in case of EINTR */
|
||||
do {
|
||||
len = v9fs_co_preadv(pdu, fidp, sg, cnt, off);
|
||||
len = v9fs_co_preadv(pdu, fidp, qiov.iov, qiov.niov, off);
|
||||
if (len >= 0) {
|
||||
off += len;
|
||||
count += len;
|
||||
@@ -1875,11 +1870,12 @@ static void v9fs_read(void *opaque)
|
||||
err = len;
|
||||
goto out;
|
||||
}
|
||||
sg = adjust_sg(sg, len, &cnt);
|
||||
} while (count < max_count && len > 0);
|
||||
err = offset;
|
||||
err += pdu_marshal(pdu, offset, "d", count);
|
||||
err += count;
|
||||
qemu_iovec_destroy(&qiov);
|
||||
qemu_iovec_destroy(&qiov_full);
|
||||
} else if (fidp->fid_type == P9_FID_XATTR) {
|
||||
err = v9fs_xattr_read(s, pdu, fidp, off, max_count);
|
||||
} else {
|
||||
@@ -1966,8 +1962,9 @@ static void v9fs_readdir(void *opaque)
|
||||
V9fsFidState *fidp;
|
||||
ssize_t retval = 0;
|
||||
size_t offset = 7;
|
||||
int64_t initial_offset;
|
||||
int32_t count, max_count;
|
||||
uint64_t initial_offset;
|
||||
int32_t count;
|
||||
uint32_t max_count;
|
||||
V9fsPDU *pdu = opaque;
|
||||
V9fsState *s = pdu->s;
|
||||
|
||||
@@ -2005,7 +2002,7 @@ out_nofid:
|
||||
}
|
||||
|
||||
static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
|
||||
int64_t off, int32_t count,
|
||||
uint64_t off, uint32_t count,
|
||||
struct iovec *sg, int cnt)
|
||||
{
|
||||
int i, to_copy;
|
||||
@@ -2050,22 +2047,22 @@ out:
|
||||
|
||||
static void v9fs_write(void *opaque)
|
||||
{
|
||||
int cnt;
|
||||
ssize_t err;
|
||||
int32_t fid;
|
||||
int64_t off;
|
||||
int32_t count;
|
||||
uint64_t off;
|
||||
uint32_t count;
|
||||
int32_t len = 0;
|
||||
int32_t total = 0;
|
||||
size_t offset = 7;
|
||||
V9fsFidState *fidp;
|
||||
struct iovec iov[128]; /* FIXME: bad, bad, bad */
|
||||
struct iovec *sg = iov;
|
||||
V9fsPDU *pdu = opaque;
|
||||
V9fsState *s = pdu->s;
|
||||
QEMUIOVector qiov_full;
|
||||
QEMUIOVector qiov;
|
||||
|
||||
pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt);
|
||||
trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, cnt);
|
||||
offset += pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count);
|
||||
v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true);
|
||||
trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, qiov_full.niov);
|
||||
|
||||
fidp = get_fid(pdu, fid);
|
||||
if (fidp == NULL) {
|
||||
@@ -2081,20 +2078,23 @@ static void v9fs_write(void *opaque)
|
||||
/*
|
||||
* setxattr operation
|
||||
*/
|
||||
err = v9fs_xattr_write(s, pdu, fidp, off, count, sg, cnt);
|
||||
err = v9fs_xattr_write(s, pdu, fidp, off, count,
|
||||
qiov_full.iov, qiov_full.niov);
|
||||
goto out;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
sg = cap_sg(sg, count, &cnt);
|
||||
qemu_iovec_init(&qiov, qiov_full.niov);
|
||||
do {
|
||||
qemu_iovec_reset(&qiov);
|
||||
qemu_iovec_copy(&qiov, &qiov_full, total, qiov_full.size - total);
|
||||
if (0) {
|
||||
print_sg(sg, cnt);
|
||||
print_sg(qiov.iov, qiov.niov);
|
||||
}
|
||||
/* Loop in case of EINTR */
|
||||
do {
|
||||
len = v9fs_co_pwritev(pdu, fidp, sg, cnt, off);
|
||||
len = v9fs_co_pwritev(pdu, fidp, qiov.iov, qiov.niov, off);
|
||||
if (len >= 0) {
|
||||
off += len;
|
||||
total += len;
|
||||
@@ -2103,16 +2103,20 @@ static void v9fs_write(void *opaque)
|
||||
if (len < 0) {
|
||||
/* IO error return the error */
|
||||
err = len;
|
||||
goto out;
|
||||
goto out_qiov;
|
||||
}
|
||||
sg = adjust_sg(sg, len, &cnt);
|
||||
} while (total < count && len > 0);
|
||||
|
||||
offset = 7;
|
||||
offset += pdu_marshal(pdu, offset, "d", total);
|
||||
err = offset;
|
||||
trace_v9fs_write_return(pdu->tag, pdu->id, total, err);
|
||||
out_qiov:
|
||||
qemu_iovec_destroy(&qiov);
|
||||
out:
|
||||
put_fid(pdu, fidp);
|
||||
out_nofid:
|
||||
qemu_iovec_destroy(&qiov_full);
|
||||
complete_pdu(s, pdu, err);
|
||||
}
|
||||
|
||||
|
@@ -156,7 +156,7 @@ typedef struct V9fsFidState V9fsFidState;
|
||||
|
||||
typedef struct V9fsString
|
||||
{
|
||||
int16_t size;
|
||||
uint16_t size;
|
||||
char *data;
|
||||
} V9fsString;
|
||||
|
||||
@@ -246,8 +246,7 @@ typedef struct V9fsState
|
||||
V9fsFidState *fid_list;
|
||||
FileOperations *ops;
|
||||
FsContext ctx;
|
||||
uint16_t tag_len;
|
||||
uint8_t *tag;
|
||||
char *tag;
|
||||
size_t config_size;
|
||||
enum p9_proto_version proto_version;
|
||||
int32_t msize;
|
||||
@@ -256,6 +255,8 @@ typedef struct V9fsState
|
||||
* on rename.
|
||||
*/
|
||||
CoRwlock rename_lock;
|
||||
int32_t root_fid;
|
||||
Error *migration_blocker;
|
||||
} V9fsState;
|
||||
|
||||
typedef struct V9fsStatState {
|
||||
|
@@ -466,6 +466,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
|
||||
bytes = split_size;
|
||||
if (tp->size + bytes > msh)
|
||||
bytes = msh - tp->size;
|
||||
|
||||
bytes = MIN(sizeof(tp->data) - tp->size, bytes);
|
||||
pci_dma_read(&s->dev, addr, tp->data + tp->size, bytes);
|
||||
if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
|
||||
memmove(tp->header, tp->data, hdr);
|
||||
@@ -481,6 +483,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
|
||||
// context descriptor TSE is not set, while data descriptor TSE is set
|
||||
DBGOUT(TXERR, "TCP segmentaion Error\n");
|
||||
} else {
|
||||
split_size = MIN(sizeof(tp->data) - tp->size, split_size);
|
||||
pci_dma_read(&s->dev, addr, tp->data + tp->size, split_size);
|
||||
tp->size += split_size;
|
||||
}
|
||||
@@ -577,7 +580,7 @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
|
||||
if (rctl & E1000_RCTL_UPE) // promiscuous
|
||||
return 1;
|
||||
|
||||
if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE)) // promiscuous mcast
|
||||
if ((buf[0] & 1)) //&& (rctl & E1000_RCTL_MPE)) // promiscuous mcast
|
||||
return 1;
|
||||
|
||||
if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "mc146818rtc.h"
|
||||
#include "blockdev.h"
|
||||
#include "exec-memory.h"
|
||||
#include "sysbus.h" /* SysBusDevice */
|
||||
|
||||
//#define DEBUG_BOARD_INIT
|
||||
|
||||
@@ -72,6 +73,11 @@ typedef struct {
|
||||
SerialState *uart;
|
||||
} MaltaFPGAState;
|
||||
|
||||
typedef struct {
|
||||
SysBusDevice busdev;
|
||||
qemu_irq *i8259;
|
||||
} MaltaState;
|
||||
|
||||
static ISADevice *pit;
|
||||
|
||||
static struct _loaderparams {
|
||||
@@ -775,7 +781,7 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
int64_t kernel_entry;
|
||||
PCIBus *pci_bus;
|
||||
CPUState *env;
|
||||
qemu_irq *i8259 = NULL, *isa_irq;
|
||||
qemu_irq *isa_irq;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
int piix4_devfn;
|
||||
i2c_bus *smbus;
|
||||
@@ -787,6 +793,11 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
int fl_sectors = 0;
|
||||
int be;
|
||||
|
||||
DeviceState *dev = qdev_create(NULL, "mips-malta");
|
||||
MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
/* Make sure the first 3 serial ports are associated with a device. */
|
||||
for(i = 0; i < 3; i++) {
|
||||
if (!serial_hds[i]) {
|
||||
@@ -932,7 +943,7 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
* qemu_irq_proxy() adds an extra bit of indirection, allowing us
|
||||
* to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
|
||||
*/
|
||||
isa_irq = qemu_irq_proxy(&i8259, 16);
|
||||
isa_irq = qemu_irq_proxy(&s->i8259, 16);
|
||||
|
||||
/* Northbridge */
|
||||
pci_bus = gt64120_register(isa_irq);
|
||||
@@ -944,9 +955,9 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
|
||||
/* Interrupt controller */
|
||||
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
|
||||
i8259 = i8259_init(env->irq[2]);
|
||||
s->i8259 = i8259_init(env->irq[2]);
|
||||
|
||||
isa_bus_irqs(i8259);
|
||||
isa_bus_irqs(s->i8259);
|
||||
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
|
||||
usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
|
||||
smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
|
||||
@@ -990,6 +1001,20 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
}
|
||||
}
|
||||
|
||||
static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SysBusDeviceInfo mips_malta_device = {
|
||||
.init = mips_malta_sysbus_device_init,
|
||||
.qdev.name = "mips-malta",
|
||||
.qdev.size = sizeof(MaltaState),
|
||||
.qdev.props = (Property[]) {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
}
|
||||
};
|
||||
|
||||
static QEMUMachine mips_malta_machine = {
|
||||
.name = "malta",
|
||||
.desc = "MIPS Malta Core LV",
|
||||
@@ -998,9 +1023,15 @@ static QEMUMachine mips_malta_machine = {
|
||||
.is_default = 1,
|
||||
};
|
||||
|
||||
static void mips_malta_device_init(void)
|
||||
{
|
||||
sysbus_register_withprop(&mips_malta_device);
|
||||
}
|
||||
|
||||
static void mips_malta_machine_init(void)
|
||||
{
|
||||
qemu_register_machine(&mips_malta_machine);
|
||||
}
|
||||
|
||||
device_init(mips_malta_device_init);
|
||||
machine_init(mips_malta_machine_init);
|
||||
|
@@ -106,6 +106,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset)
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpcore_timer_write(mpcore_timer_state *s, int offset,
|
||||
|
41
hw/pc_piix.c
41
hw/pc_piix.c
@@ -306,6 +306,14 @@ static QEMUMachine pc_machine_v1_0 = {
|
||||
.is_default = 1,
|
||||
};
|
||||
|
||||
static QEMUMachine pc_machine_v0_15 = {
|
||||
.name = "pc-0.15",
|
||||
.desc = "Standard PC",
|
||||
.init = pc_init_pci,
|
||||
.max_cpus = 255,
|
||||
.is_default = 1,
|
||||
};
|
||||
|
||||
static QEMUMachine pc_machine_v0_14 = {
|
||||
.name = "pc-0.14",
|
||||
.desc = "Standard PC",
|
||||
@@ -320,6 +328,22 @@ static QEMUMachine pc_machine_v0_14 = {
|
||||
.driver = "qxl-vga",
|
||||
.property = "revision",
|
||||
.value = stringify(2),
|
||||
},{
|
||||
.driver = "virtio-blk-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-serial-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-net-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-balloon-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
@@ -359,6 +383,10 @@ static QEMUMachine pc_machine_v0_13 = {
|
||||
.driver = "virtio-net-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-balloon-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "AC97",
|
||||
.property = "use_broken_id",
|
||||
@@ -406,6 +434,10 @@ static QEMUMachine pc_machine_v0_12 = {
|
||||
.driver = "virtio-net-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-balloon-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "AC97",
|
||||
.property = "use_broken_id",
|
||||
@@ -461,6 +493,10 @@ static QEMUMachine pc_machine_v0_11 = {
|
||||
.driver = "virtio-net-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-balloon-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "AC97",
|
||||
.property = "use_broken_id",
|
||||
@@ -528,6 +564,10 @@ static QEMUMachine pc_machine_v0_10 = {
|
||||
.driver = "virtio-net-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "virtio-balloon-pci",
|
||||
.property = "event_idx",
|
||||
.value = "off",
|
||||
},{
|
||||
.driver = "AC97",
|
||||
.property = "use_broken_id",
|
||||
@@ -557,6 +597,7 @@ static QEMUMachine xenfv_machine = {
|
||||
static void pc_machine_init(void)
|
||||
{
|
||||
qemu_register_machine(&pc_machine_v1_0);
|
||||
qemu_register_machine(&pc_machine_v0_15);
|
||||
qemu_register_machine(&pc_machine_v0_14);
|
||||
qemu_register_machine(&pc_machine_v0_13);
|
||||
qemu_register_machine(&pc_machine_v0_12);
|
||||
|
@@ -112,6 +112,7 @@ static void spin_kick(void *data)
|
||||
|
||||
env->halted = 0;
|
||||
env->exception_index = -1;
|
||||
env->stopped = 0;
|
||||
qemu_cpu_kick(env);
|
||||
}
|
||||
|
||||
|
@@ -351,6 +351,8 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
|
||||
fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
|
||||
}
|
||||
|
||||
spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
|
||||
|
||||
_FDT((fdt_pack(fdt)));
|
||||
|
||||
cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
|
||||
|
@@ -454,7 +454,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb,
|
||||
reg[0].size = 0;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; i < PCI_NUM_REGIONS; ++i) {
|
||||
for (i = 0; i < ARRAY_SIZE(bars); ++i) {
|
||||
if (0 == dev->io_regions[i].size) {
|
||||
continue;
|
||||
}
|
||||
|
@@ -749,21 +749,95 @@ static void spapr_vio_register_devices(void)
|
||||
device_init(spapr_vio_register_devices)
|
||||
|
||||
#ifdef CONFIG_FDT
|
||||
static int compare_reg(const void *p1, const void *p2)
|
||||
{
|
||||
VIOsPAPRDevice const *dev1, *dev2;
|
||||
|
||||
dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1;
|
||||
dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2;
|
||||
|
||||
if (dev1->reg < dev2->reg) {
|
||||
return -1;
|
||||
}
|
||||
if (dev1->reg == dev2->reg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dev1->reg > dev2->reg */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
|
||||
{
|
||||
DeviceState *qdev;
|
||||
int ret = 0;
|
||||
DeviceState *qdev, **qdevs;
|
||||
int i, num, ret = 0;
|
||||
|
||||
/* Count qdevs on the bus list */
|
||||
num = 0;
|
||||
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
||||
num++;
|
||||
}
|
||||
|
||||
/* Copy out into an array of pointers */
|
||||
qdevs = g_malloc(sizeof(qdev) * num);
|
||||
num = 0;
|
||||
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
|
||||
qdevs[num++] = qdev;
|
||||
}
|
||||
|
||||
/* Sort the array */
|
||||
qsort(qdevs, num, sizeof(qdev), compare_reg);
|
||||
|
||||
/* Hack alert. Give the devices to libfdt in reverse order, we happen
|
||||
* to know that will mean they are in forward order in the tree. */
|
||||
for (i = num - 1; i >= 0; i--) {
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
|
||||
|
||||
ret = vio_make_devnode(dev, fdt);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
free(qdevs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus)
|
||||
{
|
||||
VIOsPAPRDevice *dev;
|
||||
char *name, *path;
|
||||
int ret, offset;
|
||||
|
||||
dev = spapr_vty_get_default(bus);
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
offset = fdt_path_offset(fdt, "/chosen");
|
||||
if (offset < 0) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
name = vio_format_dev_name(dev);
|
||||
if (!name) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (asprintf(&path, "/vdevice/%s", name) < 0) {
|
||||
path = NULL;
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fdt_setprop_string(fdt, offset, "linux,stdout-path", path);
|
||||
out:
|
||||
free(name);
|
||||
free(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_FDT */
|
||||
|
@@ -83,6 +83,7 @@ extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
||||
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
||||
extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
|
||||
extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
|
||||
extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
|
||||
|
||||
extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
|
||||
|
||||
@@ -108,6 +109,8 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev);
|
||||
void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd);
|
||||
void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg);
|
||||
|
||||
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
|
||||
|
||||
int spapr_tce_set_bypass(uint32_t unit, uint32_t enable);
|
||||
void spapr_vio_quiesce(void);
|
||||
|
||||
|
@@ -156,24 +156,53 @@ static VIOsPAPRDeviceInfo spapr_vty = {
|
||||
},
|
||||
};
|
||||
|
||||
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
|
||||
{
|
||||
VIOsPAPRDevice *sdev, *selected;
|
||||
DeviceState *iter;
|
||||
|
||||
/*
|
||||
* To avoid the console bouncing around we want one VTY to be
|
||||
* the "default". We haven't really got anything to go on, so
|
||||
* arbitrarily choose the one with the lowest reg value.
|
||||
*/
|
||||
|
||||
selected = NULL;
|
||||
QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
|
||||
/* Only look at VTY devices */
|
||||
if (iter->info != &spapr_vty.qdev) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sdev = DO_UPCAST(VIOsPAPRDevice, qdev, iter);
|
||||
|
||||
/* First VTY we've found, so it is selected for now */
|
||||
if (!selected) {
|
||||
selected = sdev;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Choose VTY with lowest reg value */
|
||||
if (sdev->reg < selected->reg) {
|
||||
selected = sdev;
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
|
||||
{
|
||||
VIOsPAPRDevice *sdev;
|
||||
|
||||
sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
if (!sdev && reg == 0) {
|
||||
DeviceState *qdev;
|
||||
|
||||
/* Hack for kernel early debug, which always specifies reg==0.
|
||||
* We search all VIO devices, and grab the first available vty
|
||||
* device. This attempts to mimic existing PowerVM behaviour
|
||||
* We search all VIO devices, and grab the vty with the lowest
|
||||
* reg. This attempts to mimic existing PowerVM behaviour
|
||||
* (early debug does work there, despite having no vty with
|
||||
* reg==0. */
|
||||
QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
|
||||
if (qdev->info == &spapr_vty.qdev) {
|
||||
return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
|
||||
}
|
||||
}
|
||||
return spapr_vty_get_default(spapr->vio_bus);
|
||||
}
|
||||
|
||||
return sdev;
|
||||
|
12
hw/usb-msd.c
12
hw/usb-msd.c
@@ -278,6 +278,18 @@ static void usb_msd_handle_reset(USBDevice *dev)
|
||||
MSDState *s = (MSDState *)dev;
|
||||
|
||||
DPRINTF("Reset\n");
|
||||
if (s->req) {
|
||||
scsi_req_cancel(s->req);
|
||||
}
|
||||
assert(s->req == NULL);
|
||||
|
||||
if (s->packet) {
|
||||
USBPacket *p = s->packet;
|
||||
s->packet = NULL;
|
||||
p->result = USB_RET_STALL;
|
||||
usb_packet_complete(dev, p);
|
||||
}
|
||||
|
||||
s->mode = USB_MSDM_CBW;
|
||||
}
|
||||
|
||||
|
@@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
||||
if (ret == len) {
|
||||
td.cbp = 0;
|
||||
} else {
|
||||
td.cbp += ret;
|
||||
if ((td.cbp & 0xfff) + ret > 0xfff) {
|
||||
td.cbp &= 0xfff;
|
||||
td.cbp |= td.be & ~0xfff;
|
||||
td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
|
||||
} else {
|
||||
td.cbp += ret;
|
||||
}
|
||||
}
|
||||
td.flags |= OHCI_TD_T1;
|
||||
|
@@ -266,7 +266,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
|
||||
proxy->ioeventfd_started = false;
|
||||
}
|
||||
|
||||
static void virtio_pci_reset(DeviceState *d)
|
||||
void virtio_pci_reset(DeviceState *d)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
|
@@ -45,6 +45,7 @@ typedef struct {
|
||||
} VirtIOPCIProxy;
|
||||
|
||||
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
|
||||
void virtio_pci_reset(DeviceState *d);
|
||||
|
||||
/* Virtio ABI version, if we increment this, we break the guest driver. */
|
||||
#define VIRTIO_PCI_ABI_VERSION 0
|
||||
|
67
linux-user/binfmt.c
Normal file
67
linux-user/binfmt.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define ARCH_NAME "x86_64"
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
char *binfmt;
|
||||
char **new_argv;
|
||||
|
||||
/*
|
||||
* Check if our file name ends with -binfmt
|
||||
*/
|
||||
binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt");
|
||||
if (strcmp(binfmt, "-binfmt")) {
|
||||
fprintf(stderr, "%s: Invalid executable name\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
binfmt[0] = '\0';
|
||||
/* Now argv[0] is the real qemu binary name */
|
||||
|
||||
#ifdef ARCH_NAME
|
||||
{
|
||||
char *hostbin;
|
||||
char *guestarch;
|
||||
|
||||
guestarch = strrchr(argv[0], '-') ;
|
||||
if (!guestarch) {
|
||||
goto skip;
|
||||
}
|
||||
guestarch++;
|
||||
asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
|
||||
if (!access(hostbin, X_OK)) {
|
||||
/*
|
||||
* We found a host binary replacement for the non-host binary. Let's
|
||||
* use that instead!
|
||||
*/
|
||||
return execve(hostbin, &argv[2], envp);
|
||||
}
|
||||
}
|
||||
skip:
|
||||
#endif
|
||||
|
||||
new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
|
||||
if (argc > 3) {
|
||||
memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));
|
||||
}
|
||||
new_argv[0] = argv[0];
|
||||
new_argv[1] = (char *)"-0";
|
||||
new_argv[2] = argv[2];
|
||||
new_argv[3] = argv[1];
|
||||
new_argv[argc + 1] = NULL;
|
||||
|
||||
return execve(new_argv[0], new_argv, envp);
|
||||
}
|
@@ -1245,6 +1245,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
struct image_info *interp_info)
|
||||
{
|
||||
abi_ulong sp;
|
||||
abi_ulong sp_auxv;
|
||||
int size;
|
||||
int i;
|
||||
abi_ulong u_rand_bytes;
|
||||
@@ -1316,6 +1317,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
sp -= n; put_user_ual(id, sp); \
|
||||
} while(0)
|
||||
|
||||
sp_auxv = sp;
|
||||
NEW_AUX_ENT (AT_NULL, 0);
|
||||
|
||||
/* There must be exactly DLINFO_ITEMS entries here. */
|
||||
@@ -1346,6 +1348,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
#undef NEW_AUX_ENT
|
||||
|
||||
info->saved_auxv = sp;
|
||||
info->auxv_len = sp_auxv - sp;
|
||||
|
||||
sp = loader_build_argptr(envc, argc, sp, p, 0);
|
||||
return sp;
|
||||
@@ -2329,9 +2332,8 @@ static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
|
||||
{
|
||||
elf_addr_t auxv = (elf_addr_t)ts->info->saved_auxv;
|
||||
elf_addr_t orig_auxv = auxv;
|
||||
abi_ulong val;
|
||||
void *ptr;
|
||||
int i, len;
|
||||
int len = ts->info->auxv_len;
|
||||
|
||||
/*
|
||||
* Auxiliary vector is stored in target process stack. It contains
|
||||
@@ -2339,15 +2341,6 @@ static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
|
||||
* strictly necessary but we do it here for sake of completeness.
|
||||
*/
|
||||
|
||||
/* find out lenght of the vector, AT_NULL is terminator */
|
||||
i = len = 0;
|
||||
do {
|
||||
get_user_ual(val, auxv);
|
||||
i += 2;
|
||||
auxv += 2 * sizeof (elf_addr_t);
|
||||
} while (val != AT_NULL);
|
||||
len = i * sizeof (elf_addr_t);
|
||||
|
||||
/* read in whole auxv vector and copy it to memelfnote */
|
||||
ptr = lock_user(VERIFY_READ, orig_auxv, len, 0);
|
||||
if (ptr != NULL) {
|
||||
|
@@ -74,6 +74,8 @@
|
||||
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
|
||||
IOCTL(BLKRASET, 0, TYPE_INT)
|
||||
IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
#ifdef FIBMAP
|
||||
IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
|
||||
#endif
|
||||
@@ -314,6 +316,11 @@
|
||||
IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
|
||||
IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
|
||||
|
||||
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
|
||||
#ifdef __powerpc__
|
||||
#include "ioctls_alsa.h"
|
||||
#endif
|
||||
|
||||
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
|
||||
@@ -345,3 +352,35 @@
|
||||
IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
|
||||
IOCTL(VT_RELDISP, 0, TYPE_INT)
|
||||
IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
|
||||
|
||||
IOCTL(DM_VERSION, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_REMOVE_ALL, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_LIST_DEVICES, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_CREATE, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_REMOVE, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_RENAME, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_SUSPEND, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_STATUS, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_WAIT, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_TABLE_LOAD, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_TABLE_CLEAR, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_TABLE_DEPS, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_TABLE_STATUS, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_LIST_VERSIONS,IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_TARGET_MSG, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm,
|
||||
MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
|
||||
|
467
linux-user/ioctls_alsa.h
Normal file
467
linux-user/ioctls_alsa.h
Normal file
@@ -0,0 +1,467 @@
|
||||
#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int)
|
||||
#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
|
||||
#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info)
|
||||
#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client)
|
||||
#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool)
|
||||
#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool)
|
||||
#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs)
|
||||
#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info)
|
||||
#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t)
|
||||
#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21)
|
||||
#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int)
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
|
||||
#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int)
|
||||
#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct sndrv_hwdep_info)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct sndrv_hwdep_dsp_status)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
|
||||
#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
|
||||
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct sndrv_pcm_info)
|
||||
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
|
||||
#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct sndrv_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct sndrv_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
|
||||
#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct sndrv_pcm_sw_params)
|
||||
#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct sndrv_pcm_status)
|
||||
#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, sndrv_pcm_sframes_t)
|
||||
#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
|
||||
#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr)
|
||||
#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct sndrv_pcm_channel_info)
|
||||
#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
|
||||
#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
|
||||
#define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
|
||||
#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
|
||||
#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
|
||||
#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
|
||||
#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, sndrv_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
|
||||
#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
|
||||
#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, sndrv_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct sndrv_xferi)
|
||||
#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct sndrv_xferi)
|
||||
#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct sndrv_xfern)
|
||||
#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct sndrv_xfern)
|
||||
#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
|
||||
#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
|
||||
#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct sndrv_rawmidi_info)
|
||||
#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct sndrv_rawmidi_params)
|
||||
#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct sndrv_rawmidi_status)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
|
||||
#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
|
||||
#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct sndrv_timer_id)
|
||||
#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
|
||||
#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct sndrv_timer_ginfo)
|
||||
#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct sndrv_timer_gparams)
|
||||
#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct sndrv_timer_gstatus)
|
||||
#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct sndrv_timer_select)
|
||||
#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct sndrv_timer_info)
|
||||
#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct sndrv_timer_params)
|
||||
#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct sndrv_timer_status)
|
||||
#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
|
||||
#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
|
||||
#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
|
||||
#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
|
||||
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
|
||||
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct sndrv_ctl_card_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct sndrv_ctl_elem_list)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct sndrv_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct sndrv_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct sndrv_hwdep_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
|
||||
#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct sndrv_pcm_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct sndrv_rawmidi_info)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
|
||||
#define SNDRV_IOCTL_READV _IOW('K', 0x00, struct sndrv_xferv)
|
||||
#define SNDRV_IOCTL_WRITEV _IOW('K', 0x01, struct sndrv_xferv)
|
||||
#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80)
|
||||
#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81)
|
||||
#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
|
||||
#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int)
|
||||
#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
|
||||
#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12)
|
||||
#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14)
|
||||
#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15)
|
||||
#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
|
||||
#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
|
||||
#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
|
||||
|
||||
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_PVERSION TARGET_IOR ('S', 0x00, int)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CLIENT_ID TARGET_IOR ('S', 0x01, int)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SYSTEM_INFO TARGET_IOWRU('S', 0x02)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_RUNNING_MODE TARGET_IOWRU('S', 0x03)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_INFO TARGET_IOWRU('S', 0x10)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_INFO TARGET_IOWU ('S', 0x11)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_PORT TARGET_IOWRU('S', 0x20)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_PORT TARGET_IOWU ('S', 0x21)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_PORT_INFO TARGET_IOWRU('S', 0x22)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_PORT_INFO TARGET_IOWU ('S', 0x23)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT TARGET_IOWU ('S', 0x30)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT TARGET_IOWU ('S', 0x31)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_QUEUE TARGET_IOWRU('S', 0x32)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_QUEUE TARGET_IOWU ('S', 0x33)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_INFO TARGET_IOWRU('S', 0x34)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_INFO TARGET_IOWRU('S', 0x35)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE TARGET_IOWRU('S', 0x36)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS TARGET_IOWRU('S', 0x40)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO TARGET_IOWRU('S', 0x41)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO TARGET_IOWU ('S', 0x42)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER TARGET_IOWRU('S', 0x43)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER TARGET_IOWU ('S', 0x44)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER TARGET_IOWRU('S', 0x45)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER TARGET_IOWU ('S', 0x46)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC TARGET_IOWRU('S', 0x53)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC TARGET_IOWU ('S', 0x54)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT TARGET_IOWRU('S', 0x49)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT TARGET_IOWU ('S', 0x4a)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_POOL TARGET_IOWRU('S', 0x4b)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_POOL TARGET_IOWU ('S', 0x4c)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_REMOVE_EVENTS TARGET_IOWU ('S', 0x4e)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_SUBS TARGET_IOWRU('S', 0x4f)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION TARGET_IOWRU('S', 0x50)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT TARGET_IOWRU('S', 0x51)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT TARGET_IOWRU('S', 0x52)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_INFO TARGET_IORU('H', 0x20)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_RESET TARGET_IO ('H', 0x21)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_PLAY_NOTE TARGET_IOWU('H', 0x22)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_VOICE TARGET_IOWU('H', 0x23)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_PARAMS TARGET_IOWU('H', 0x24)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_MODE TARGET_IOW('H', 0x25, int)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_CONNECTION TARGET_IOW('H', 0x26, int)
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_PVERSION TARGET_IOR ('H', 0x00, int)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_INFO TARGET_IORU ('H', 0x01)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_STATUS TARGET_IORU('H', 0x02)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_LOAD TARGET_IOWU('H', 0x03)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PVERSION TARGET_IOR('A', 0x00, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_INFO TARGET_IORU('A', 0x01)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_TSTAMP TARGET_IOW('A', 0x02, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_REFINE TARGET_IOWRU('A', 0x10)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_PARAMS TARGET_IOWRU('A', 0x11)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_FREE TARGET_IO('A', 0x12)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_SW_PARAMS TARGET_IOWRU('A', 0x13)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_STATUS TARGET_IORU('A', 0x20)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DELAY TARGET_IORU('A', 0x21)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HWSYNC TARGET_IO('A', 0x22)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_SYNC_PTR TARGET_IOWRU('A', 0x23)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_CHANNEL_INFO TARGET_IORU('A', 0x32)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PREPARE TARGET_IO('A', 0x40)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_RESET TARGET_IO('A', 0x41)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_START TARGET_IO('A', 0x42)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DROP TARGET_IO('A', 0x43)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DRAIN TARGET_IO('A', 0x44)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PAUSE TARGET_IOW('A', 0x45, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_REWIND TARGET_IOWU('A', 0x46)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_RESUME TARGET_IO('A', 0x47)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_XRUN TARGET_IO('A', 0x48)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_FORWARD TARGET_IOWU('A', 0x49)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_WRITEI_FRAMES TARGET_IOWU('A', 0x50)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_READI_FRAMES TARGET_IORU('A', 0x51)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_WRITEN_FRAMES TARGET_IOWU('A', 0x52)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_READN_FRAMES TARGET_IORU('A', 0x53)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_LINK TARGET_IOW('A', 0x60, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_UNLINK TARGET_IO('A', 0x61)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_PVERSION TARGET_IOR('W', 0x00, int)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_INFO TARGET_IORU('W', 0x01)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_PARAMS TARGET_IOWRU('W', 0x10)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_STATUS TARGET_IOWRU('W', 0x20)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_DROP TARGET_IOW('W', 0x30, int)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_DRAIN TARGET_IOW('W', 0x31, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PVERSION TARGET_IOR('T', 0x00, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_NEXT_DEVICE TARGET_IOWRU('T', 0x01)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_TREAD TARGET_IOW('T', 0x02, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GINFO TARGET_IOWRU('T', 0x03)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GPARAMS TARGET_IOWU('T', 0x04)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GSTATUS TARGET_IOWRU('T', 0x05)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_SELECT TARGET_IOWU('T', 0x10)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_INFO TARGET_IORU('T', 0x11)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PARAMS TARGET_IOWU('T', 0x12)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_STATUS TARGET_IORU('T', 0x14)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_START TARGET_IO('T', 0xa0)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_STOP TARGET_IO('T', 0xa1)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_CONTINUE TARGET_IO('T', 0xa2)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PAUSE TARGET_IO('T', 0xa3)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PVERSION TARGET_IOR('U', 0x00, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_CARD_INFO TARGET_IORU('U', 0x01)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LIST TARGET_IOWRU('U', 0x10)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_INFO TARGET_IOWRU('U', 0x11)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_READ TARGET_IOWRU('U', 0x12)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_WRITE TARGET_IOWRU('U', 0x13)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LOCK TARGET_IOWU('U', 0x14)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_UNLOCK TARGET_IOWU('U', 0x15)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS TARGET_IOWR('U', 0x16, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_ADD TARGET_IOWRU('U', 0x17)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REPLACE TARGET_IOWRU('U', 0x18)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REMOVE TARGET_IOWRU('U', 0x19)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_READ TARGET_IOWRU('U', 0x1a)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_WRITE TARGET_IOWRU('U', 0x1b)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_COMMAND TARGET_IOWRU('U', 0x1c)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE TARGET_IOWR('U', 0x20, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_INFO TARGET_IORU('U', 0x21)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE TARGET_IOR('U', 0x30, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_INFO TARGET_IOWRU('U', 0x31)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE TARGET_IOW('U', 0x32, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE TARGET_IOWR('U', 0x40, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_INFO TARGET_IOWRU('U', 0x41)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE TARGET_IOW('U', 0x42, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_POWER TARGET_IOWR('U', 0xd0, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_POWER_STATE TARGET_IOR('U', 0xd1, int)
|
||||
#define TARGET_SNDRV_IOCTL_READV TARGET_IOWU('K', 0x00)
|
||||
#define TARGET_SNDRV_IOCTL_WRITEV TARGET_IOWU('K', 0x01)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_INFO TARGET_IORU ('H', 0x10)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_POKE TARGET_IOWU ('H', 0x11)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_PEEK TARGET_IOWRU('H', 0x12)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_SETUP TARGET_IOW ('H', 0x20, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_POKE TARGET_IOWU ('H', 0x21)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_PEEK TARGET_IOWRU('H', 0x22)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_POKE TARGET_IOWU ('H', 0x30)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_PEEK TARGET_IOWRU('H', 0x31)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PVERSION TARGET_IOR ('H', 0x40, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_STOP TARGET_IO ('H', 0x80)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CONTINUE TARGET_IO ('H', 0x81)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER TARGET_IO ('H', 0x82)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_SINGLE_STEP TARGET_IOW ('H', 0x83, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_DBG_READ TARGET_IOR ('H', 0x84, int)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_PEAK_RMS TARGET_IORU('H', 0x40)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_CONFIG_INFO TARGET_IORU('H', 0x41)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE TARGET_IOWU('H', 0x42)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_VERSION TARGET_IORU('H', 0x43)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_MIXER TARGET_IORU('H', 0x44)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_9632_AEB TARGET_IORU('H', 0x45)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_INFO TARGET_IORU('H', 0x10)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_LOAD_CODE TARGET_IOWU('H', 0x11)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_UNLOAD_CODE TARGET_IO('H', 0x12)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_START TARGET_IOWU('H', 0x13)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_STOP TARGET_IO('H', 0x14)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_PAUSE TARGET_IO('H', 0x15)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_RESTART TARGET_IO('H', 0x16)
|
||||
#define TARGET_SND_SSCAPE_LOAD_BOOTB TARGET_IOWRU('P', 100)
|
||||
#define TARGET_SND_SSCAPE_LOAD_MCODE TARGET_IOWU ('P', 101)
|
||||
|
||||
IOCTL( SNDRV_SEQ_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CLIENT_ID , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SYSTEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_system_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_RUNNING_MODE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_running_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CREATE_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_DELETE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_PORT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_PORT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CREATE_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_DELETE_QUEUE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_status)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_POOL , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_POOL , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_REMOVE_EVENTS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_remove_events)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_SUBS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_query_subs)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_info)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_RESET , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_PLAY_NOTE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_note)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_VOICE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_voice)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_params)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_MODE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_CONNECTION , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_DSP_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_status)) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_DSP_LOAD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_image)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_TSTAMP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_REFINE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_FREE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_SW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_status)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DELAY , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HWSYNC , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_SYNC_PTR , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sync_ptr)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_CHANNEL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_channel_info)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PREPARE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_RESET , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_START , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DROP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DRAIN , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PAUSE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_REWIND , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_RESUME , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_XRUN , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_FORWARD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_WRITEI_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_READI_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_WRITEN_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_READN_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_LINK , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_UNLINK , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_params)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_status)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_DROP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_DRAIN , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_NEXT_DEVICE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_id)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_TREAD , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GINFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_ginfo)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GPARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gparams)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GSTATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gstatus)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_SELECT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_select)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_info)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_params)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_status)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_START , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_CONTINUE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PAUSE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_CARD_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_card_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_LIST , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_list)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_LOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_UNLOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_ADD , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_REPLACE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_REMOVE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_COMMAND , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_HWDEP_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_POWER , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_POWER_STATE , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_IOCTL_READV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
|
||||
IOCTL( SNDRV_IOCTL_WRITEV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_info)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_SETUP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CONTINUE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_SINGLE_STEP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_DBG_READ , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_PEAK_RMS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_peak_rms)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_CONFIG_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_config_info)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_hdsp_firmware)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_VERSION , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_version)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_MIXER , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_mixer)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_9632_AEB , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_9632_aeb)) )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_info)) )
|
||||
#if _IOC_SIZEBITS > 13
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_LOAD_CODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_microcode)) )
|
||||
#endif
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_UNLOAD_CODE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_START , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_start)) )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_PAUSE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_RESTART , 0, TYPE_NULL )
|
||||
IOCTL( SND_SSCAPE_LOAD_BOOTB , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sscape_bootblock)) )
|
||||
IOCTL( SND_SSCAPE_LOAD_MCODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sscape_microcode)) )
|
1740
linux-user/ioctls_alsa_structs.h
Normal file
1740
linux-user/ioctls_alsa_structs.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -48,10 +48,22 @@ unsigned long mmap_min_addr;
|
||||
#if defined(CONFIG_USE_GUEST_BASE)
|
||||
unsigned long guest_base;
|
||||
int have_guest_base;
|
||||
#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
|
||||
/*
|
||||
* When running 32-on-64 we should make sure we can fit all of the possible
|
||||
* guest address space into a contiguous chunk of virtual host memory.
|
||||
*
|
||||
* This way we will never overlap with our own libraries or binaries or stack
|
||||
* or anything else that QEMU maps.
|
||||
*/
|
||||
unsigned long reserved_va = 0xf7000000;
|
||||
#else
|
||||
unsigned long reserved_va;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void usage(void);
|
||||
extern int use_stopflag;
|
||||
|
||||
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
||||
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
|
||||
@@ -817,15 +829,22 @@ void cpu_loop(CPUARMState *env)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
env->regs[0] = do_syscall(env,
|
||||
n,
|
||||
env->regs[0],
|
||||
env->regs[1],
|
||||
env->regs[2],
|
||||
env->regs[3],
|
||||
env->regs[4],
|
||||
env->regs[5],
|
||||
0, 0);
|
||||
TaskState *ts = ((CPUState*)env)->opaque;
|
||||
target_ulong r;
|
||||
r = do_syscall(env, n, env->regs[0], env->regs[1],
|
||||
env->regs[2], env->regs[3], env->regs[4],
|
||||
env->regs[5], 0, 0);
|
||||
if ((r == -EINTR) && ts->signal_restart &&
|
||||
syscall_restartable(n)) {
|
||||
if (env->thumb) {
|
||||
env->regs[15] -= 2;
|
||||
} else {
|
||||
env->regs[15] -= 4;
|
||||
}
|
||||
} else {
|
||||
env->regs[0] = r;
|
||||
}
|
||||
ts->signal_restart = 0;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
@@ -3072,6 +3091,11 @@ static void handle_arg_reserved_va(const char *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_arg_nostopflag(const char *arg)
|
||||
{
|
||||
use_stopflag = 0;
|
||||
}
|
||||
|
||||
static void handle_arg_singlestep(const char *arg)
|
||||
{
|
||||
singlestep = 1;
|
||||
@@ -3125,6 +3149,8 @@ struct qemu_argument arg_table[] = {
|
||||
#endif
|
||||
{"d", "QEMU_LOG", true, handle_arg_log,
|
||||
"options", "activate log"},
|
||||
{"no-stopflag", "QEMU_NOSTOPFLAG", false, handle_arg_nostopflag,
|
||||
"", "run in singlestep mode"},
|
||||
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
|
||||
"pagesize", "set the host page size to 'pagesize'"},
|
||||
{"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
|
||||
@@ -3411,6 +3437,7 @@ int main(int argc, char **argv, char **envp)
|
||||
guest_base = HOST_PAGE_ALIGN((unsigned long)p);
|
||||
}
|
||||
qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
|
||||
mmap_next_start = reserved_va;
|
||||
}
|
||||
|
||||
if (reserved_va || have_guest_base) {
|
||||
@@ -3477,11 +3504,6 @@ int main(int argc, char **argv, char **envp)
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < target_argc; i++) {
|
||||
free(target_argv[i]);
|
||||
}
|
||||
free(target_argv);
|
||||
|
||||
for (wrk = target_environ; *wrk; wrk++) {
|
||||
free(*wrk);
|
||||
}
|
||||
|
@@ -216,6 +216,7 @@ struct target_pt_regs {
|
||||
#undef TARGET_ENOTRECOVERABLE
|
||||
#define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
|
||||
|
||||
|
||||
/* Nasty hack: define a fake errno value for use by sigreturn. */
|
||||
#define TARGET_QEMU_ESIGRETURN 255
|
||||
|
||||
#define UNAME_MACHINE "mips64"
|
||||
|
@@ -210,9 +210,9 @@ static int mmap_frag(abi_ulong real_start,
|
||||
/* Cygwin doesn't have a whole lot of address space. */
|
||||
# define TASK_UNMAPPED_BASE 0x18000000
|
||||
#else
|
||||
# define TASK_UNMAPPED_BASE 0x40000000
|
||||
# define TASK_UNMAPPED_BASE 0x18000000
|
||||
#endif
|
||||
static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
|
||||
abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
|
||||
|
||||
unsigned long last_brk;
|
||||
|
||||
@@ -222,7 +222,7 @@ unsigned long last_brk;
|
||||
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
|
||||
{
|
||||
abi_ulong addr;
|
||||
abi_ulong last_addr;
|
||||
abi_ulong end_addr;
|
||||
int prot;
|
||||
int looped = 0;
|
||||
|
||||
@@ -230,25 +230,38 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
|
||||
return (abi_ulong)-1;
|
||||
}
|
||||
|
||||
last_addr = start;
|
||||
for (addr = start; last_addr + size != addr; addr += qemu_host_page_size) {
|
||||
if (last_addr + size >= RESERVED_VA
|
||||
|| (abi_ulong)(last_addr + size) < last_addr) {
|
||||
size = HOST_PAGE_ALIGN(size);
|
||||
end_addr = start + size;
|
||||
if (end_addr > RESERVED_VA) {
|
||||
end_addr = RESERVED_VA;
|
||||
}
|
||||
addr = end_addr - qemu_host_page_size;
|
||||
|
||||
while (1) {
|
||||
if (addr > end_addr) {
|
||||
if (looped) {
|
||||
return (abi_ulong)-1;
|
||||
}
|
||||
last_addr = qemu_host_page_size;
|
||||
addr = 0;
|
||||
end_addr = RESERVED_VA;
|
||||
addr = end_addr - qemu_host_page_size;
|
||||
looped = 1;
|
||||
continue;
|
||||
}
|
||||
prot = page_get_flags(addr);
|
||||
if (prot) {
|
||||
last_addr = addr + qemu_host_page_size;
|
||||
end_addr = addr;
|
||||
}
|
||||
if (addr + size == end_addr) {
|
||||
break;
|
||||
}
|
||||
addr -= qemu_host_page_size;
|
||||
}
|
||||
mmap_next_start = addr;
|
||||
return last_addr;
|
||||
|
||||
if (start == mmap_next_start) {
|
||||
mmap_next_start = addr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -364,6 +377,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
|
||||
}
|
||||
}
|
||||
|
||||
#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
|
||||
#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
|
||||
|
||||
/* NOTE: all the constants are the HOST ones */
|
||||
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
int flags, int fd, abi_ulong offset)
|
||||
@@ -399,6 +415,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Alsa tries to communcate with the kernel via mmap. This usually
|
||||
* is a good idea when user- and kernelspace are running on the
|
||||
* same architecture but does not work out when not. To make alsa
|
||||
* not to use mmap, we can just have it fail on the mmap calls that
|
||||
* would initiate this.
|
||||
*/
|
||||
if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset & ~TARGET_PAGE_MASK) {
|
||||
errno = EINVAL;
|
||||
goto fail;
|
||||
@@ -560,6 +587,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
page_dump(stdout);
|
||||
printf("\n");
|
||||
#endif
|
||||
tb_invalidate_phys_range(start, start + len, 0);
|
||||
mmap_unlock();
|
||||
return start;
|
||||
fail:
|
||||
@@ -741,6 +769,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
page_set_flags(old_addr, old_addr + old_size, 0);
|
||||
page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
|
||||
}
|
||||
tb_invalidate_phys_range(new_addr, new_addr + new_size, 0);
|
||||
mmap_unlock();
|
||||
return new_addr;
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ struct image_info {
|
||||
abi_ulong code_offset;
|
||||
abi_ulong data_offset;
|
||||
abi_ulong saved_auxv;
|
||||
abi_ulong auxv_len;
|
||||
abi_ulong arg_start;
|
||||
abi_ulong arg_end;
|
||||
int personality;
|
||||
@@ -135,6 +136,8 @@ typedef struct TaskState {
|
||||
struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
|
||||
struct sigqueue *first_free; /* first free siginfo queue entry */
|
||||
int signal_pending; /* non zero if a signal may be pending */
|
||||
int signal_in_syscall; /* non zero if we are in do_syscall() */
|
||||
int signal_restart; /* non zero if we need to restart a syscall */
|
||||
} __attribute__((aligned(16))) TaskState;
|
||||
|
||||
extern char *exec_path;
|
||||
@@ -201,6 +204,7 @@ char *target_strerror(int err);
|
||||
int get_osversion(void);
|
||||
void fork_start(void);
|
||||
void fork_end(int child);
|
||||
int syscall_restartable(int syscall_nr);
|
||||
|
||||
/* Return true if the proposed guest_base is suitable for the guest.
|
||||
* The guest code may leave a page mapped and populate it if the
|
||||
@@ -250,6 +254,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
abi_ulong new_addr);
|
||||
int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern unsigned long last_brk;
|
||||
extern abi_ulong mmap_next_start;
|
||||
void mmap_lock(void);
|
||||
void mmap_unlock(void);
|
||||
abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <assert.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "qemu.h"
|
||||
#include "qemu-common.h"
|
||||
@@ -373,6 +374,10 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
host_sig = target_to_host_signal(target_sig);
|
||||
gdb_signalled(thread_env, target_sig);
|
||||
|
||||
if (target_sig == 6) {
|
||||
goto no_core;
|
||||
}
|
||||
|
||||
/* dump core if supported by target binary format */
|
||||
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
|
||||
stop_all_tasks();
|
||||
@@ -390,6 +395,8 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
target_sig, strsignal(host_sig), "core dumped" );
|
||||
}
|
||||
|
||||
no_core:
|
||||
|
||||
/* The proper exit code for dying from an uncaught signal is
|
||||
* -<signal>. The kernel doesn't allow exit() or _exit() to pass
|
||||
* a negative value. To get the proper exit code we need to
|
||||
@@ -475,6 +482,11 @@ int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
|
||||
k->pending = 1;
|
||||
/* signal that a new signal is pending */
|
||||
ts->signal_pending = 1;
|
||||
/* check if we have to restart the current syscall */
|
||||
if ((sigact_table[sig - 1].sa_flags & SA_RESTART) &&
|
||||
ts->signal_in_syscall) {
|
||||
ts->signal_restart = 1;
|
||||
}
|
||||
return 1; /* indicates that the signal was queued */
|
||||
}
|
||||
}
|
||||
@@ -607,8 +619,24 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
if (host_sig != SIGSEGV && host_sig != SIGBUS) {
|
||||
sigfillset(&act1.sa_mask);
|
||||
act1.sa_flags = SA_SIGINFO;
|
||||
#ifdef TARGET_ARM
|
||||
/* Breaks boehm-gc, we have to do this manually */
|
||||
/*
|
||||
* Unfortunately our hacks only work as long as we don't do parallel
|
||||
* signal delivery and futexes, so let's do a dirty hack here to
|
||||
* pin our guest process to a single host CPU if we're using the
|
||||
* boehm-gc.
|
||||
*/
|
||||
if ((k->sa_flags & TARGET_SA_RESTART) && host_sig == SIGPWR) {
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(0, &mask);
|
||||
sched_setaffinity(0, sizeof(mask), &mask);
|
||||
}
|
||||
#else
|
||||
if (k->sa_flags & TARGET_SA_RESTART)
|
||||
act1.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
/* NOTE: it is important to update the host kernel signal
|
||||
ignore state to avoid getting unexpected interrupted
|
||||
syscalls */
|
||||
|
@@ -284,8 +284,13 @@ print_ipc(const struct syscallname *name,
|
||||
static void
|
||||
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
||||
{
|
||||
if( ret == -1 ) {
|
||||
gemu_log(" = -1 errno=%d (%s)\n", errno, target_strerror(errno));
|
||||
char *errstr = NULL;
|
||||
|
||||
if (ret == -1) {
|
||||
errstr = target_strerror(errno);
|
||||
}
|
||||
if ((ret == -1) && errstr) {
|
||||
gemu_log(" = -1 errno=%d (%s)\n", errno, errstr);
|
||||
} else {
|
||||
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
||||
}
|
||||
@@ -1515,14 +1520,19 @@ void
|
||||
print_syscall_ret(int num, abi_long ret)
|
||||
{
|
||||
int i;
|
||||
char *errstr = NULL;
|
||||
|
||||
for(i=0;i<nsyscalls;i++)
|
||||
if( scnames[i].nr == num ) {
|
||||
if( scnames[i].result != NULL ) {
|
||||
scnames[i].result(&scnames[i],ret);
|
||||
} else {
|
||||
if( ret < 0 ) {
|
||||
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret));
|
||||
if (ret < 0) {
|
||||
errstr = target_strerror(-ret);
|
||||
}
|
||||
if (errstr) {
|
||||
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
|
||||
-ret, errstr);
|
||||
} else {
|
||||
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
|
||||
}
|
||||
|
@@ -95,6 +95,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
||||
#endif
|
||||
#include <linux/fb.h>
|
||||
#include <linux/vt.h>
|
||||
#include <linux/dm-ioctl.h>
|
||||
#include "linux_loop.h"
|
||||
#include "cpu-uname.h"
|
||||
|
||||
@@ -731,6 +732,9 @@ static inline int is_error(abi_long ret)
|
||||
|
||||
char *target_strerror(int err)
|
||||
{
|
||||
if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
|
||||
return NULL;
|
||||
}
|
||||
return strerror(target_to_host_errno(err));
|
||||
}
|
||||
|
||||
@@ -3317,6 +3321,231 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
|
||||
abi_long cmd, abi_long arg)
|
||||
{
|
||||
void *argptr;
|
||||
struct dm_ioctl *host_dm;
|
||||
abi_long guest_data;
|
||||
uint32_t guest_data_size;
|
||||
int target_size;
|
||||
const argtype *arg_type = ie->arg_type;
|
||||
abi_long ret;
|
||||
void *big_buf = NULL;
|
||||
char *host_data;
|
||||
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||
if (!argptr) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto out;
|
||||
}
|
||||
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
|
||||
unlock_user(argptr, arg, 0);
|
||||
|
||||
/* buf_temp is too small, so fetch things into a bigger buffer */
|
||||
big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
|
||||
memcpy(big_buf, buf_temp, target_size);
|
||||
buf_temp = big_buf;
|
||||
host_dm = big_buf;
|
||||
|
||||
guest_data = arg + host_dm->data_start;
|
||||
if ((guest_data - arg) < 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
guest_data_size = host_dm->data_size - host_dm->data_start;
|
||||
host_data = (char*)host_dm + host_dm->data_start;
|
||||
|
||||
argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
|
||||
switch (ie->host_cmd) {
|
||||
case DM_REMOVE_ALL:
|
||||
case DM_LIST_DEVICES:
|
||||
case DM_DEV_CREATE:
|
||||
case DM_DEV_REMOVE:
|
||||
case DM_DEV_SUSPEND:
|
||||
case DM_DEV_STATUS:
|
||||
case DM_DEV_WAIT:
|
||||
case DM_TABLE_STATUS:
|
||||
case DM_TABLE_CLEAR:
|
||||
case DM_TABLE_DEPS:
|
||||
case DM_LIST_VERSIONS:
|
||||
/* no input data */
|
||||
break;
|
||||
case DM_DEV_RENAME:
|
||||
case DM_DEV_SET_GEOMETRY:
|
||||
/* data contains only strings */
|
||||
memcpy(host_data, argptr, guest_data_size);
|
||||
break;
|
||||
case DM_TARGET_MSG:
|
||||
memcpy(host_data, argptr, guest_data_size);
|
||||
*(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
|
||||
break;
|
||||
case DM_TABLE_LOAD:
|
||||
{
|
||||
void *gspec = argptr;
|
||||
void *cur_data = host_data;
|
||||
const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
|
||||
int spec_size = thunk_type_size(arg_type, 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < host_dm->target_count; i++) {
|
||||
struct dm_target_spec *spec = cur_data;
|
||||
uint32_t next;
|
||||
int slen;
|
||||
|
||||
thunk_convert(spec, gspec, arg_type, THUNK_HOST);
|
||||
slen = strlen((char*)gspec + spec_size) + 1;
|
||||
next = spec->next;
|
||||
spec->next = sizeof(*spec) + slen;
|
||||
strcpy((char*)&spec[1], gspec + spec_size);
|
||||
gspec += next;
|
||||
cur_data += spec->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = -TARGET_EINVAL;
|
||||
goto out;
|
||||
}
|
||||
unlock_user(argptr, guest_data, 0);
|
||||
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
|
||||
if (!is_error(ret)) {
|
||||
guest_data = arg + host_dm->data_start;
|
||||
guest_data_size = host_dm->data_size - host_dm->data_start;
|
||||
argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
|
||||
switch (ie->host_cmd) {
|
||||
case DM_REMOVE_ALL:
|
||||
case DM_DEV_CREATE:
|
||||
case DM_DEV_REMOVE:
|
||||
case DM_DEV_RENAME:
|
||||
case DM_DEV_SUSPEND:
|
||||
case DM_DEV_STATUS:
|
||||
case DM_TABLE_LOAD:
|
||||
case DM_TABLE_CLEAR:
|
||||
case DM_TARGET_MSG:
|
||||
case DM_DEV_SET_GEOMETRY:
|
||||
/* no return data */
|
||||
break;
|
||||
case DM_LIST_DEVICES:
|
||||
{
|
||||
struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
|
||||
uint32_t remaining_data = guest_data_size;
|
||||
void *cur_data = argptr;
|
||||
const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
|
||||
int nl_size = 12; /* can't use thunk_size due to alignment */
|
||||
|
||||
while (1) {
|
||||
uint32_t next = nl->next;
|
||||
if (next) {
|
||||
nl->next = nl_size + (strlen(nl->name) + 1);
|
||||
}
|
||||
if (remaining_data < nl->next) {
|
||||
host_dm->flags |= DM_BUFFER_FULL_FLAG;
|
||||
break;
|
||||
}
|
||||
thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
|
||||
strcpy(cur_data + nl_size, nl->name);
|
||||
cur_data += nl->next;
|
||||
remaining_data -= nl->next;
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
nl = (void*)nl + next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DM_DEV_WAIT:
|
||||
case DM_TABLE_STATUS:
|
||||
{
|
||||
struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
|
||||
void *cur_data = argptr;
|
||||
const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
|
||||
int spec_size = thunk_type_size(arg_type, 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < host_dm->target_count; i++) {
|
||||
uint32_t next = spec->next;
|
||||
int slen = strlen((char*)&spec[1]) + 1;
|
||||
spec->next = (cur_data - argptr) + spec_size + slen;
|
||||
if (guest_data_size < spec->next) {
|
||||
host_dm->flags |= DM_BUFFER_FULL_FLAG;
|
||||
break;
|
||||
}
|
||||
thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
|
||||
strcpy(cur_data + spec_size, (char*)&spec[1]);
|
||||
cur_data = argptr + spec->next;
|
||||
spec = (void*)host_dm + host_dm->data_start + next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DM_TABLE_DEPS:
|
||||
{
|
||||
void *hdata = (void*)host_dm + host_dm->data_start;
|
||||
int count = *(uint32_t*)hdata;
|
||||
uint64_t *hdev = hdata + 8;
|
||||
uint64_t *gdev = argptr + 8;
|
||||
int i;
|
||||
|
||||
*(uint32_t*)argptr = tswap32(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
*gdev = tswap64(*hdev);
|
||||
gdev++;
|
||||
hdev++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DM_LIST_VERSIONS:
|
||||
{
|
||||
struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
|
||||
uint32_t remaining_data = guest_data_size;
|
||||
void *cur_data = argptr;
|
||||
const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
|
||||
int vers_size = thunk_type_size(arg_type, 0);
|
||||
|
||||
while (1) {
|
||||
uint32_t next = vers->next;
|
||||
if (next) {
|
||||
vers->next = vers_size + (strlen(vers->name) + 1);
|
||||
}
|
||||
if (remaining_data < vers->next) {
|
||||
host_dm->flags |= DM_BUFFER_FULL_FLAG;
|
||||
break;
|
||||
}
|
||||
thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
|
||||
strcpy(cur_data + vers_size, vers->name);
|
||||
cur_data += vers->next;
|
||||
remaining_data -= vers->next;
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
vers = (void*)vers + next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = -TARGET_EINVAL;
|
||||
goto out;
|
||||
}
|
||||
unlock_user(argptr, guest_data, guest_data_size);
|
||||
|
||||
argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
|
||||
if (!argptr) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto out;
|
||||
}
|
||||
thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
|
||||
unlock_user(argptr, arg, target_size);
|
||||
}
|
||||
out:
|
||||
if (big_buf) {
|
||||
free(big_buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IOCTLEntry ioctl_entries[] = {
|
||||
#define IOCTL(cmd, access, ...) \
|
||||
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
|
||||
@@ -3340,7 +3569,12 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
|
||||
ie = ioctl_entries;
|
||||
for(;;) {
|
||||
if (ie->target_cmd == 0) {
|
||||
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
|
||||
int i;
|
||||
gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
|
||||
for (i = 0; ioctl_entries[i].target_cmd; i++) {
|
||||
if ((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
|
||||
gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
|
||||
}
|
||||
return -TARGET_ENOSYS;
|
||||
}
|
||||
if (ie->target_cmd == cmd)
|
||||
@@ -3369,6 +3603,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
switch(ie->access) {
|
||||
/* FIXME: actually the direction given in the ioctl should be
|
||||
* correct so we can assume the communication is uni-directional.
|
||||
* The alsa developers did not like this concept though and
|
||||
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
|
||||
/*
|
||||
case IOC_R:
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
|
||||
if (!is_error(ret)) {
|
||||
@@ -3387,6 +3626,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
|
||||
unlock_user(argptr, arg, 0);
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
case IOC_RW:
|
||||
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||
@@ -4600,6 +4840,254 @@ int get_osversion(void)
|
||||
return osversion;
|
||||
}
|
||||
|
||||
|
||||
static int open_self_maps(void *cpu_env, int fd)
|
||||
{
|
||||
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
|
||||
TaskState *ts = ((CPUState *)cpu_env)->opaque;
|
||||
#endif
|
||||
FILE *fp;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
fp = fopen("/proc/self/maps", "r");
|
||||
if (fp == NULL) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
int fields, dev_maj, dev_min, inode;
|
||||
uint64_t min, max, offset;
|
||||
char flag_r, flag_w, flag_x, flag_p;
|
||||
char path[512] = "";
|
||||
fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
|
||||
" %512s", &min, &max, &flag_r, &flag_w, &flag_x,
|
||||
&flag_p, &offset, &dev_maj, &dev_min, &inode, path);
|
||||
|
||||
if ((fields < 10) || (fields > 11)) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(path, "[stack]", 7)) {
|
||||
continue;
|
||||
}
|
||||
if (h2g_valid(min) && h2g_valid(max)) {
|
||||
dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx " %c%c%c%c %08"
|
||||
PRIx64 " %02x:%02x %d%s%s\n", h2g(min), h2g(max), flag_r,
|
||||
flag_w, flag_x, flag_p, offset, dev_maj, dev_min, inode,
|
||||
path[0] ? " " : "", path);
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(fp);
|
||||
|
||||
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
|
||||
dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
|
||||
(unsigned long long)ts->info->stack_limit,
|
||||
(unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
|
||||
& TARGET_PAGE_MASK,
|
||||
(unsigned long long)0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_self_stat(void *cpu_env, int fd)
|
||||
{
|
||||
TaskState *ts = ((CPUState *)cpu_env)->opaque;
|
||||
abi_ulong start_stack = ts->info->start_stack;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 44; i++) {
|
||||
char buf[128];
|
||||
int len;
|
||||
uint64_t val = 0;
|
||||
|
||||
if (i == 0) {
|
||||
/* pid */
|
||||
val = getpid();
|
||||
snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
|
||||
} else if (i == 1) {
|
||||
/* app name */
|
||||
snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
|
||||
} else if (i == 27) {
|
||||
/* stack bottom */
|
||||
val = start_stack;
|
||||
snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
|
||||
} else {
|
||||
/* for the rest, there is MasterCard */
|
||||
snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
|
||||
}
|
||||
|
||||
len = strlen(buf);
|
||||
if (write(fd, buf, len) != len) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_self_auxv(void *cpu_env, int fd)
|
||||
{
|
||||
TaskState *ts = ((CPUState *)cpu_env)->opaque;
|
||||
abi_ulong auxv = ts->info->saved_auxv;
|
||||
abi_ulong len = ts->info->auxv_len;
|
||||
char *ptr;
|
||||
|
||||
/*
|
||||
* Auxiliary vector is stored in target process stack.
|
||||
* read in whole auxv vector and copy it to file
|
||||
*/
|
||||
ptr = lock_user(VERIFY_READ, auxv, len, 0);
|
||||
if (ptr != NULL) {
|
||||
while (len > 0) {
|
||||
ssize_t r;
|
||||
r = write(fd, ptr, len);
|
||||
if (r <= 0) {
|
||||
break;
|
||||
}
|
||||
len -= r;
|
||||
ptr += r;
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
unlock_user(ptr, auxv, len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
|
||||
{
|
||||
struct fake_open {
|
||||
const char *filename;
|
||||
int (*fill)(void *cpu_env, int fd);
|
||||
};
|
||||
const struct fake_open *fake_open;
|
||||
static const struct fake_open fakes[] = {
|
||||
{ "/proc/self/maps", open_self_maps },
|
||||
{ "/proc/self/stat", open_self_stat },
|
||||
{ "/proc/self/auxv", open_self_auxv },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
for (fake_open = fakes; fake_open->filename; fake_open++) {
|
||||
if (!strncmp(pathname, fake_open->filename,
|
||||
strlen(fake_open->filename))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fake_open->filename) {
|
||||
const char *tmpdir;
|
||||
char filename[PATH_MAX];
|
||||
int fd, r;
|
||||
|
||||
/* create temporary file to map stat to */
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (!tmpdir)
|
||||
tmpdir = "/tmp";
|
||||
snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
|
||||
fd = mkstemp(filename);
|
||||
if (fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
unlink(filename);
|
||||
|
||||
if ((r = fake_open->fill(cpu_env, fd))) {
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
return get_errno(open(path(pathname), flags, mode));
|
||||
}
|
||||
|
||||
int syscall_restartable(int syscall_nr)
|
||||
{
|
||||
switch (syscall_nr) {
|
||||
#ifdef TARGET_NR_sigsuspend
|
||||
case TARGET_NR_sigsuspend:
|
||||
#endif
|
||||
#ifdef TARGET_NR_pause
|
||||
case TARGET_NR_pause:
|
||||
#endif
|
||||
#ifdef TARGET_NR_setsockopt
|
||||
case TARGET_NR_setsockopt:
|
||||
#endif
|
||||
#ifdef TARGET_NR_accept
|
||||
case TARGET_NR_accept:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recv
|
||||
case TARGET_NR_recv:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recvfrom
|
||||
case TARGET_NR_recvfrom:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recvmsg
|
||||
case TARGET_NR_recvmsg:
|
||||
#endif
|
||||
#ifdef TARGET_NR_socketcall
|
||||
case TARGET_NR_socketcall:
|
||||
#endif
|
||||
#ifdef TARGET_NR_connect
|
||||
case TARGET_NR_connect:
|
||||
#endif
|
||||
#ifdef TARGET_NR_send
|
||||
case TARGET_NR_send:
|
||||
#endif
|
||||
#ifdef TARGET_NR_sendmsg
|
||||
case TARGET_NR_sendmsg:
|
||||
#endif
|
||||
#ifdef TARGET_NR_sendto
|
||||
case TARGET_NR_sendto:
|
||||
#endif
|
||||
#ifdef TARGET_NR_poll
|
||||
case TARGET_NR_poll:
|
||||
#endif
|
||||
#ifdef TARGET_NR_ppoll
|
||||
case TARGET_NR_ppoll:
|
||||
#endif
|
||||
#if defined(TARGET_NR_select)
|
||||
case TARGET_NR_select:
|
||||
#endif
|
||||
#ifdef TARGET_NR_pselect6
|
||||
case TARGET_NR_pselect6:
|
||||
#endif
|
||||
#ifdef TARGET_NR__newselect
|
||||
case TARGET_NR__newselect:
|
||||
#endif
|
||||
#ifdef TARGET_NR_msgrcv
|
||||
case TARGET_NR_msgrcv:
|
||||
#endif
|
||||
#ifdef TARGET_NR_msgsnd
|
||||
case TARGET_NR_msgsnd:
|
||||
#endif
|
||||
#ifdef TARGET_NR_semop
|
||||
case TARGET_NR_semop:
|
||||
#endif
|
||||
#ifdef TARGET_NR_ipc
|
||||
case TARGET_NR_ipc:
|
||||
#endif
|
||||
#ifdef TARGET_NR_clock_nanosleep
|
||||
case TARGET_NR_clock_nanosleep:
|
||||
#endif
|
||||
case TARGET_NR_rt_sigsuspend:
|
||||
case TARGET_NR_rt_sigtimedwait:
|
||||
case TARGET_NR_nanosleep:
|
||||
case TARGET_NR_close:
|
||||
/* can not be restarted */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* every other syscall can be restarted */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do_syscall() should always have a single exit point at the end so
|
||||
that actions, such as logging of syscall results, can be performed.
|
||||
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
|
||||
@@ -4612,6 +5100,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
struct stat st;
|
||||
struct statfs stfs;
|
||||
void *p;
|
||||
TaskState *ts = ((CPUState*)cpu_env)->opaque;
|
||||
|
||||
if (!ts->signal_restart) {
|
||||
/* remember syscall info for restart */
|
||||
ts->signal_in_syscall = 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
gemu_log("syscall %d", num);
|
||||
@@ -4685,9 +5179,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_open:
|
||||
if (!(p = lock_user_string(arg1)))
|
||||
goto efault;
|
||||
ret = get_errno(open(path(p),
|
||||
target_to_host_bitmask(arg2, fcntl_flags_tbl),
|
||||
arg3));
|
||||
ret = get_errno(do_open(cpu_env, p,
|
||||
target_to_host_bitmask(arg2, fcntl_flags_tbl),
|
||||
arg3));
|
||||
unlock_user(p, arg1, 0);
|
||||
break;
|
||||
#if defined(TARGET_NR_openat) && defined(__NR_openat)
|
||||
@@ -4715,7 +5209,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
int status;
|
||||
ret = get_errno(waitpid(arg1, &status, arg3));
|
||||
if (!is_error(ret) && arg2
|
||||
if (!is_error(ret) && arg2 && ret
|
||||
&& put_user_s32(host_to_target_waitstatus(status), arg2))
|
||||
goto efault;
|
||||
}
|
||||
@@ -5655,6 +6149,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_gettimeofday:
|
||||
{
|
||||
struct timeval tv;
|
||||
if(copy_from_user_timeval(&tv, arg1))
|
||||
goto efault;
|
||||
ret = get_errno(gettimeofday(&tv, NULL));
|
||||
if (!is_error(ret)) {
|
||||
if (copy_to_user_timeval(arg1, &tv))
|
||||
@@ -6271,7 +6767,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
rusage_ptr = NULL;
|
||||
ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
|
||||
if (!is_error(ret)) {
|
||||
if (status_ptr) {
|
||||
if (status_ptr && ret) {
|
||||
status = host_to_target_waitstatus(status);
|
||||
if (put_user_s32(status, status_ptr))
|
||||
goto efault;
|
||||
@@ -6906,7 +7402,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
unlock_user(p, arg1, ret);
|
||||
break;
|
||||
case TARGET_NR_capget:
|
||||
goto unimplemented;
|
||||
goto unimplemented_nowarn;
|
||||
case TARGET_NR_capset:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_sigaltstack:
|
||||
@@ -7521,8 +8017,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
|
||||
cmd = target_to_host_fcntl_cmd(arg2);
|
||||
if (cmd == -TARGET_EINVAL)
|
||||
return cmd;
|
||||
if (cmd == -TARGET_EINVAL) {
|
||||
ret = cmd;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch(arg2) {
|
||||
case TARGET_F_GETLK64:
|
||||
@@ -7775,6 +8273,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_timer_create)
|
||||
case TARGET_NR_timer_create:
|
||||
goto unimplemented_nowarn;
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
|
||||
case TARGET_NR_tkill:
|
||||
ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
|
||||
@@ -7976,7 +8479,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
#endif /* CONFIG_EVENTFD */
|
||||
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
|
||||
case TARGET_NR_fallocate:
|
||||
#if TARGET_ABI_BITS == 32
|
||||
ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
|
||||
target_offset64(arg5, arg6)));
|
||||
#else
|
||||
ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_SYNC_FILE_RANGE)
|
||||
@@ -8154,6 +8662,7 @@ fail:
|
||||
#endif
|
||||
if(do_strace)
|
||||
print_syscall_ret(num, ret);
|
||||
ts->signal_in_syscall = 0;
|
||||
return ret;
|
||||
efault:
|
||||
ret = -TARGET_EFAULT;
|
||||
|
@@ -832,9 +832,11 @@ struct target_pollfd {
|
||||
#define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
|
||||
#define TARGET_BLKSSZGET TARGET_IO(0x12,104)/* get block device sector size */
|
||||
/* A jump here: 108-111 have been used for various private purposes. */
|
||||
#define TARGET_BLKBSZGET TARGET_IOR(0x12,112,sizeof(int))
|
||||
#define TARGET_BLKBSZSET TARGET_IOW(0x12,113,sizeof(int))
|
||||
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
|
||||
#define TARGET_BLKBSZGET TARGET_IOR(0x12,112,int)
|
||||
#define TARGET_BLKBSZSET TARGET_IOW(0x12,113,int)
|
||||
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
|
||||
/* return device size in bytes
|
||||
(u64 *arg) */
|
||||
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
|
||||
@@ -989,6 +991,24 @@ struct target_pollfd {
|
||||
#define TARGET_VT_RELDISP 0x5605
|
||||
#define TARGET_VT_DISALLOCATE 0x5608
|
||||
|
||||
/* device mapper */
|
||||
#define TARGET_DM_VERSION TARGET_IOWRU(0xfd, 0x00)
|
||||
#define TARGET_DM_REMOVE_ALL TARGET_IOWRU(0xfd, 0x01)
|
||||
#define TARGET_DM_LIST_DEVICES TARGET_IOWRU(0xfd, 0x02)
|
||||
#define TARGET_DM_DEV_CREATE TARGET_IOWRU(0xfd, 0x03)
|
||||
#define TARGET_DM_DEV_REMOVE TARGET_IOWRU(0xfd, 0x04)
|
||||
#define TARGET_DM_DEV_RENAME TARGET_IOWRU(0xfd, 0x05)
|
||||
#define TARGET_DM_DEV_SUSPEND TARGET_IOWRU(0xfd, 0x06)
|
||||
#define TARGET_DM_DEV_STATUS TARGET_IOWRU(0xfd, 0x07)
|
||||
#define TARGET_DM_DEV_WAIT TARGET_IOWRU(0xfd, 0x08)
|
||||
#define TARGET_DM_TABLE_LOAD TARGET_IOWRU(0xfd, 0x09)
|
||||
#define TARGET_DM_TABLE_CLEAR TARGET_IOWRU(0xfd, 0x0a)
|
||||
#define TARGET_DM_TABLE_DEPS TARGET_IOWRU(0xfd, 0x0b)
|
||||
#define TARGET_DM_TABLE_STATUS TARGET_IOWRU(0xfd, 0x0c)
|
||||
#define TARGET_DM_LIST_VERSIONS TARGET_IOWRU(0xfd, 0x0d)
|
||||
#define TARGET_DM_TARGET_MSG TARGET_IOWRU(0xfd, 0x0e)
|
||||
#define TARGET_DM_DEV_SET_GEOMETRY TARGET_IOWRU(0xfd, 0x0f)
|
||||
|
||||
/* from asm/termbits.h */
|
||||
|
||||
#define TARGET_NCC 8
|
||||
@@ -2336,3 +2356,5 @@ struct target_rlimit64 {
|
||||
uint64_t rlim_cur;
|
||||
uint64_t rlim_max;
|
||||
};
|
||||
|
||||
#include "ioctls_alsa_structs.h"
|
||||
|
@@ -80,12 +80,17 @@ STRUCT(count_info,
|
||||
STRUCT(mixer_info,
|
||||
MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10))
|
||||
|
||||
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
|
||||
#ifdef __powerpc__
|
||||
#include "syscall_types_alsa.h"
|
||||
#endif
|
||||
|
||||
/* loop device ioctls */
|
||||
STRUCT(loop_info,
|
||||
TYPE_INT, /* lo_number */
|
||||
TYPE_SHORT, /* lo_device */
|
||||
TYPE_OLDDEVT, /* lo_device */
|
||||
TYPE_ULONG, /* lo_inode */
|
||||
TYPE_SHORT, /* lo_rdevice */
|
||||
TYPE_OLDDEVT, /* lo_rdevice */
|
||||
TYPE_INT, /* lo_offset */
|
||||
TYPE_INT, /* lo_encrypt_type */
|
||||
TYPE_INT, /* lo_encrypt_key_size */
|
||||
@@ -186,6 +191,42 @@ STRUCT(vt_mode,
|
||||
TYPE_SHORT, /* acqsig */
|
||||
TYPE_SHORT) /* frsig */
|
||||
|
||||
STRUCT(dm_ioctl,
|
||||
MK_ARRAY(TYPE_INT, 3), /* version */
|
||||
TYPE_INT, /* data_size */
|
||||
TYPE_INT, /* data_start */
|
||||
TYPE_INT, /* target_count*/
|
||||
TYPE_INT, /* open_count */
|
||||
TYPE_INT, /* flags */
|
||||
TYPE_INT, /* event_nr */
|
||||
TYPE_INT, /* padding */
|
||||
TYPE_ULONGLONG, /* dev */
|
||||
MK_ARRAY(TYPE_CHAR, 128), /* name */
|
||||
MK_ARRAY(TYPE_CHAR, 129), /* uuid */
|
||||
MK_ARRAY(TYPE_CHAR, 7)) /* data */
|
||||
|
||||
STRUCT(dm_target_spec,
|
||||
TYPE_ULONGLONG, /* sector_start */
|
||||
TYPE_ULONGLONG, /* length */
|
||||
TYPE_INT, /* status */
|
||||
TYPE_INT, /* next */
|
||||
MK_ARRAY(TYPE_CHAR, 16)) /* target_type */
|
||||
|
||||
STRUCT(dm_target_deps,
|
||||
TYPE_INT, /* count */
|
||||
TYPE_INT) /* padding */
|
||||
|
||||
STRUCT(dm_name_list,
|
||||
TYPE_ULONGLONG, /* dev */
|
||||
TYPE_INT) /* next */
|
||||
|
||||
STRUCT(dm_target_versions,
|
||||
TYPE_INT, /* next */
|
||||
MK_ARRAY(TYPE_INT, 3)) /* version*/
|
||||
|
||||
STRUCT(dm_target_msg,
|
||||
TYPE_ULONGLONG) /* sector */
|
||||
|
||||
STRUCT(fiemap_extent,
|
||||
TYPE_ULONGLONG, /* fe_logical */
|
||||
TYPE_ULONGLONG, /* fe_physical */
|
||||
|
1336
linux-user/syscall_types_alsa.h
Normal file
1336
linux-user/syscall_types_alsa.h
Normal file
File diff suppressed because it is too large
Load Diff
25
net.c
25
net.c
@@ -30,6 +30,7 @@
|
||||
#include "net/dump.h"
|
||||
#include "net/slirp.h"
|
||||
#include "net/vde.h"
|
||||
#include "net/udp.h"
|
||||
#include "net/util.h"
|
||||
#include "monitor.h"
|
||||
#include "qemu-common.h"
|
||||
@@ -1031,6 +1032,29 @@ static const struct {
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
[NET_CLIENT_TYPE_UDP] = {
|
||||
.type = "udp",
|
||||
.init = net_init_udp,
|
||||
.desc = {
|
||||
NET_COMMON_PARAMS_DESC,
|
||||
{
|
||||
.name = "sport",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
|
||||
.help = "source port number",
|
||||
}, {
|
||||
.name = "daddr",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "destination IP address",
|
||||
}, {
|
||||
.name = "dport",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "destination port number",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
},
|
||||
[NET_CLIENT_TYPE_DUMP] = {
|
||||
.type = "dump",
|
||||
.init = net_init_dump,
|
||||
@@ -1348,6 +1372,7 @@ void net_check_clients(void)
|
||||
case NET_CLIENT_TYPE_USER:
|
||||
case NET_CLIENT_TYPE_TAP:
|
||||
case NET_CLIENT_TYPE_SOCKET:
|
||||
case NET_CLIENT_TYPE_UDP:
|
||||
case NET_CLIENT_TYPE_VDE:
|
||||
has_host_dev = 1;
|
||||
break;
|
||||
|
1
net.h
1
net.h
@@ -35,6 +35,7 @@ typedef enum {
|
||||
NET_CLIENT_TYPE_TAP,
|
||||
NET_CLIENT_TYPE_SOCKET,
|
||||
NET_CLIENT_TYPE_VDE,
|
||||
NET_CLIENT_TYPE_UDP,
|
||||
NET_CLIENT_TYPE_DUMP,
|
||||
|
||||
NET_CLIENT_TYPE_MAX
|
||||
|
138
net/udp.c
Normal file
138
net/udp.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* QEMU System Emulator
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
*
|
||||
* 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 "net/udp.h"
|
||||
|
||||
#include "config-host.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/udp.h>
|
||||
#endif
|
||||
|
||||
#include "net.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-option.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "sysemu.h"
|
||||
|
||||
|
||||
typedef struct UDPState {
|
||||
VLANClientState nc;
|
||||
int rfd;
|
||||
struct sockaddr_in sender;
|
||||
} UDPState;
|
||||
|
||||
static void udp_to_qemu(void *opaque)
|
||||
{
|
||||
UDPState *s = opaque;
|
||||
uint8_t buf[4096];
|
||||
int size;
|
||||
|
||||
size = recvfrom(s->rfd, (char *)buf, sizeof(buf), 0, NULL, NULL);
|
||||
if (size > 0) {
|
||||
qemu_send_packet(&s->nc, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t udp_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||
{
|
||||
UDPState *s = DO_UPCAST(UDPState, nc, nc);
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = sendto(s->rfd, (const char *)buf, size, 0, (struct sockaddr *)&s->sender, sizeof (s->sender));
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void udp_cleanup(VLANClientState *nc)
|
||||
{
|
||||
UDPState *s = DO_UPCAST(UDPState, nc, nc);
|
||||
qemu_set_fd_handler(s->rfd, NULL, NULL, NULL);
|
||||
close(s->rfd);
|
||||
}
|
||||
|
||||
static NetClientInfo net_udp_info = {
|
||||
.type = NET_CLIENT_TYPE_UDP,
|
||||
.size = sizeof(UDPState),
|
||||
.receive = udp_receive,
|
||||
.cleanup = udp_cleanup,
|
||||
};
|
||||
|
||||
static int net_udp_init(VLANState *vlan, const char *model,
|
||||
const char *name, int sport,
|
||||
const char *daddr, int dport)
|
||||
{
|
||||
VLANClientState *nc;
|
||||
UDPState *s;
|
||||
struct sockaddr_in receiver;
|
||||
int ret;
|
||||
|
||||
nc = qemu_new_net_client(&net_udp_info, vlan, NULL, model, name);
|
||||
|
||||
snprintf(nc->info_str, sizeof(nc->info_str),"udp: %i->%s:%i",
|
||||
sport, daddr, dport);
|
||||
|
||||
s = DO_UPCAST(UDPState, nc, nc);
|
||||
|
||||
s->rfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
|
||||
receiver.sin_family = AF_INET;
|
||||
receiver.sin_addr.s_addr = INADDR_ANY;
|
||||
receiver.sin_port = htons(sport);
|
||||
ret = bind(s->rfd, (struct sockaddr *)&receiver, sizeof(receiver));
|
||||
|
||||
if (ret == -1) {
|
||||
fprintf (stderr, "bind error:%s\n", strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset((char*)&s->sender, 0,sizeof(s->sender));
|
||||
s->sender.sin_family = AF_INET;
|
||||
s->sender.sin_port = htons(dport);
|
||||
inet_aton(daddr, &s->sender.sin_addr);
|
||||
|
||||
qemu_set_fd_handler(s->rfd, udp_to_qemu, NULL, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan)
|
||||
{
|
||||
const char *daddr;
|
||||
int sport, dport;
|
||||
|
||||
daddr = qemu_opt_get(opts, "daddr");
|
||||
|
||||
sport = qemu_opt_get_number(opts, "sport", 0);
|
||||
dport = qemu_opt_get_number(opts, "dport", 0);
|
||||
|
||||
if (net_udp_init(vlan, "udp", name, sport, daddr, dport) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
32
net/udp.h
Normal file
32
net/udp.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* QEMU System Emulator
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef QEMU_NET_UDP_H
|
||||
#define QEMU_NET_UDP_H
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-option.h"
|
||||
|
||||
int net_init_udp(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan);
|
||||
|
||||
#endif /* QEMU_NET_UDP_H */
|
16
ppc.ld
16
ppc.ld
@@ -49,8 +49,20 @@ SECTIONS
|
||||
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
|
||||
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
|
||||
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.rel.plt :
|
||||
{
|
||||
*(.rel.plt)
|
||||
PROVIDE (__rel_iplt_start = .);
|
||||
*(.rel.iplt)
|
||||
PROVIDE (__rel_iplt_end = .);
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(.init))
|
||||
|
16
ppc64.ld
16
ppc64.ld
@@ -54,8 +54,20 @@ SECTIONS
|
||||
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
}
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.rel.plt :
|
||||
{
|
||||
*(.rel.plt)
|
||||
PROVIDE (__rel_iplt_start = .);
|
||||
*(.rel.iplt)
|
||||
PROVIDE (__rel_iplt_end = .);
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE (__rela_iplt_end = .);
|
||||
}
|
||||
.rela.tocbss : { *(.rela.tocbss) }
|
||||
.init :
|
||||
{
|
||||
|
@@ -24,13 +24,13 @@ ETEXI
|
||||
DEF("commit", img_commit,
|
||||
"commit [-f fmt] [-t cache] filename")
|
||||
STEXI
|
||||
@item commit [-f @var{fmt}] @var{filename}
|
||||
@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
|
||||
ETEXI
|
||||
|
||||
DEF("convert", img_convert,
|
||||
"convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
|
||||
STEXI
|
||||
@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
|
||||
@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
|
||||
ETEXI
|
||||
|
||||
DEF("info", img_info,
|
||||
@@ -48,7 +48,7 @@ ETEXI
|
||||
DEF("rebase", img_rebase,
|
||||
"rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
|
||||
STEXI
|
||||
@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
|
||||
@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
|
||||
ETEXI
|
||||
|
||||
DEF("resize", img_resize,
|
||||
|
50
qemu-img.c
50
qemu-img.c
@@ -661,7 +661,7 @@ static int img_convert(int argc, char **argv)
|
||||
const uint8_t *buf1;
|
||||
BlockDriverInfo bdi;
|
||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
||||
QEMUOptionParameter *out_baseimg_param;
|
||||
QEMUOptionParameter *out_baseimg_param, *scsi;
|
||||
char *options = NULL;
|
||||
const char *snapshot_name = NULL;
|
||||
float local_progress;
|
||||
@@ -852,6 +852,12 @@ static int img_convert(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if ((scsi = get_option_parameter(param, BLOCK_OPT_SCSI)) && scsi->value.n && strcmp(drv->format_name, "vmdk")) {
|
||||
error_report("SCSI devices not supported for this file format");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create the new image */
|
||||
ret = bdrv_create(drv, out_filename, param);
|
||||
if (ret < 0) {
|
||||
@@ -1420,6 +1426,8 @@ static int img_rebase(int argc, char **argv)
|
||||
*/
|
||||
if (!unsafe) {
|
||||
uint64_t num_sectors;
|
||||
uint64_t old_backing_num_sectors;
|
||||
uint64_t new_backing_num_sectors;
|
||||
uint64_t sector;
|
||||
int n;
|
||||
uint8_t * buf_old;
|
||||
@@ -1430,6 +1438,8 @@ static int img_rebase(int argc, char **argv)
|
||||
buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
|
||||
|
||||
bdrv_get_geometry(bs, &num_sectors);
|
||||
bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
|
||||
bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
|
||||
|
||||
local_progress = (float)100 /
|
||||
(num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
|
||||
@@ -1448,16 +1458,36 @@ static int img_rebase(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Read old and new backing file */
|
||||
ret = bdrv_read(bs_old_backing, sector, buf_old, n);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading from old backing file");
|
||||
goto out;
|
||||
/*
|
||||
* Read old and new backing file and take into consideration that
|
||||
* backing files may be smaller than the COW image.
|
||||
*/
|
||||
if (sector >= old_backing_num_sectors) {
|
||||
memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
|
||||
} else {
|
||||
if (sector + n > old_backing_num_sectors) {
|
||||
n = old_backing_num_sectors - sector;
|
||||
}
|
||||
|
||||
ret = bdrv_read(bs_old_backing, sector, buf_old, n);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading from old backing file");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ret = bdrv_read(bs_new_backing, sector, buf_new, n);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading from new backing file");
|
||||
goto out;
|
||||
|
||||
if (sector >= new_backing_num_sectors) {
|
||||
memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
|
||||
} else {
|
||||
if (sector + n > new_backing_num_sectors) {
|
||||
n = new_backing_num_sectors - sector;
|
||||
}
|
||||
|
||||
ret = bdrv_read(bs_new_backing, sector, buf_new, n);
|
||||
if (ret < 0) {
|
||||
error_report("error while reading from new backing file");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* If they differ, we need to write to the COW file */
|
||||
|
@@ -45,6 +45,10 @@ indicates the consecutive number of bytes that must contain only zeros
|
||||
for qemu-img to create a sparse image during conversion. This value is rounded
|
||||
down to the nearest 512 bytes. You may use the common size suffixes like
|
||||
@code{k} for kilobytes.
|
||||
@item -t @var{cache}
|
||||
specifies the cache mode that should be used with the (destination) file. See
|
||||
the documentation of the emulator's @code{-drive cache=...} option for allowed
|
||||
values.
|
||||
@end table
|
||||
|
||||
Parameters to snapshot subcommand:
|
||||
@@ -87,11 +91,11 @@ this case. @var{backing_file} will never be modified unless you use the
|
||||
The size can also be specified using the @var{size} option with @code{-o},
|
||||
it doesn't need to be specified separately in this case.
|
||||
|
||||
@item commit [-f @var{fmt}] @var{filename}
|
||||
@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
|
||||
|
||||
Commit the changes recorded in @var{filename} in its base image.
|
||||
|
||||
@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
|
||||
@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
|
||||
|
||||
Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
|
||||
using format @var{output_fmt}. It can be optionally compressed (@code{-c}
|
||||
@@ -121,7 +125,7 @@ they are displayed too.
|
||||
|
||||
List, apply, create or delete snapshots in image @var{filename}.
|
||||
|
||||
@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
|
||||
@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
|
||||
|
||||
Changes the backing file of an image. Only the formats @code{qcow2} and
|
||||
@code{qed} support changing the backing file.
|
||||
|
10
qemu-lock.h
10
qemu-lock.h
@@ -24,6 +24,12 @@
|
||||
#include <pthread.h>
|
||||
#define spin_lock pthread_mutex_lock
|
||||
#define spin_unlock pthread_mutex_unlock
|
||||
static inline void spin_unlock_safe(pthread_mutex_t *lock)
|
||||
{
|
||||
/* unlocking an unlocked mutex results in undefined behavior */
|
||||
pthread_mutex_trylock(lock);
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
#define spinlock_t pthread_mutex_t
|
||||
#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
@@ -46,4 +52,8 @@ static inline void spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void spin_unlock_safe(spinlock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1112,6 +1112,15 @@ STEXI
|
||||
Disable HPET support.
|
||||
ETEXI
|
||||
|
||||
DEF("no-stopflag", 0, QEMU_OPTION_no_stopflag,
|
||||
"-no-stopflag use old behaviour, not inline stopflag checks\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -no-stopflag
|
||||
@findex -no-stopflag
|
||||
Implement cpu-exit by the old tb link breaking method rather than inline checks
|
||||
(this is slightly faster but racy!)
|
||||
ETEXI
|
||||
|
||||
DEF("balloon", HAS_ARG, QEMU_OPTION_balloon,
|
||||
"-balloon none disable balloon device\n"
|
||||
"-balloon virtio[,addr=str]\n"
|
||||
@@ -1217,6 +1226,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
|
||||
"-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]]\n"
|
||||
" connect the vlan 'n' to multicast maddr and port\n"
|
||||
" use 'localaddr=addr' to specify the host address to send packets from\n"
|
||||
"-net udp[,vlan=n]sport=sport,dport=dport,daddr=host\n"
|
||||
" connect the vlan 'n' to a UDP tunnel (for Dynamips/GNS3)\n"
|
||||
#ifdef CONFIG_VDE
|
||||
"-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
|
||||
" connect the vlan 'n' to port 'n' of a vde switch running\n"
|
||||
|
5
qerror.c
5
qerror.c
@@ -234,6 +234,11 @@ static const QErrorStringTable qerror_table[] = {
|
||||
.desc = "'%(device)' uses a %(format) feature which is not "
|
||||
"supported by this qemu version: %(feature)",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
|
||||
.desc = "Migration is disabled when VirtFS export path '%(path)' "
|
||||
"is mounted in the guest using mount_tag '%(tag)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_VNC_SERVER_FAILED,
|
||||
.desc = "Could not start VNC server on %(target)",
|
||||
|
3
qerror.h
3
qerror.h
@@ -192,6 +192,9 @@ QError *qobject_to_qerror(const QObject *obj);
|
||||
#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
|
||||
"{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
|
||||
|
||||
#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
|
||||
"{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }"
|
||||
|
||||
#define QERR_VNC_SERVER_FAILED \
|
||||
"{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
|
||||
|
||||
|
@@ -27,42 +27,46 @@ case "$cpu" in
|
||||
armv[4-9]*)
|
||||
cpu="arm"
|
||||
;;
|
||||
sparc*)
|
||||
cpu="sparc"
|
||||
;;
|
||||
esac
|
||||
|
||||
# register the interpreter for each cpu except for the native one
|
||||
if [ $cpu != "i386" ] ; then
|
||||
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "alpha" ] ; then
|
||||
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "arm" ] ; then
|
||||
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "sparc" ] ; then
|
||||
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "ppc" ] ; then
|
||||
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "m68k" ] ; then
|
||||
echo 'Please check cpu value and header information for m68k!'
|
||||
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "mips" ] ; then
|
||||
# FIXME: We could use the other endianness on a MIPS host.
|
||||
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "sh" ] ; then
|
||||
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
|
||||
if [ $cpu != "s390x" ] ; then
|
||||
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "s390x" ] ; then
|
||||
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
|
@@ -67,6 +67,8 @@
|
||||
#define Q_FLAG 0x80000000
|
||||
#define M_FLAG 0x40000000
|
||||
#define PFIX_FLAG 0x800 /* CRISv10 Only. */
|
||||
#define F_FLAG_V10 0x400
|
||||
#define P_FLAG_V10 0x200
|
||||
#define S_FLAG 0x200
|
||||
#define R_FLAG 0x100
|
||||
#define P_FLAG 0x80
|
||||
|
@@ -157,6 +157,7 @@ static void do_interruptv10(CPUState *env)
|
||||
/* Now that we are in kernel mode, load the handlers address. */
|
||||
env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
|
||||
env->locked_irq = 1;
|
||||
env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */
|
||||
|
||||
qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
|
||||
__func__, env->pc, ex_vec,
|
||||
|
@@ -62,6 +62,65 @@ static inline void cris_illegal_insn(DisasContext *dc)
|
||||
t_gen_raise_exception(EXCP_BREAK);
|
||||
}
|
||||
|
||||
static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
|
||||
unsigned int size, int mem_index)
|
||||
{
|
||||
int l1 = gen_new_label();
|
||||
TCGv taddr = tcg_temp_local_new();
|
||||
TCGv tval = tcg_temp_local_new();
|
||||
TCGv t1 = tcg_temp_local_new();
|
||||
dc->postinc = 0;
|
||||
cris_evaluate_flags(dc);
|
||||
|
||||
tcg_gen_mov_tl(taddr, addr);
|
||||
tcg_gen_mov_tl(tval, val);
|
||||
|
||||
/* Store only if F flag isn't set */
|
||||
tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
|
||||
if (size == 1) {
|
||||
tcg_gen_qemu_st8(tval, taddr, mem_index);
|
||||
} else if (size == 2) {
|
||||
tcg_gen_qemu_st16(tval, taddr, mem_index);
|
||||
} else {
|
||||
tcg_gen_qemu_st32(tval, taddr, mem_index);
|
||||
}
|
||||
gen_set_label(l1);
|
||||
tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */
|
||||
tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free(tval);
|
||||
tcg_temp_free(taddr);
|
||||
}
|
||||
|
||||
static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
|
||||
unsigned int size)
|
||||
{
|
||||
int mem_index = cpu_mmu_index(dc->env);
|
||||
|
||||
/* If we get a fault on a delayslot we must keep the jmp state in
|
||||
the cpu-state to be able to re-execute the jmp. */
|
||||
if (dc->delayed_branch == 1) {
|
||||
cris_store_direct_jmp(dc);
|
||||
}
|
||||
|
||||
/* Conditional writes. We only support the kind were X is known
|
||||
at translation time. */
|
||||
if (dc->flagx_known && dc->flags_x) {
|
||||
gen_store_v10_conditional(dc, addr, val, size, mem_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 1) {
|
||||
tcg_gen_qemu_st8(val, addr, mem_index);
|
||||
} else if (size == 2) {
|
||||
tcg_gen_qemu_st16(val, addr, mem_index);
|
||||
} else {
|
||||
tcg_gen_qemu_st32(val, addr, mem_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Prefix flag and register are used to handle the more complex
|
||||
addressing modes. */
|
||||
static void cris_set_prefix(DisasContext *dc)
|
||||
@@ -313,7 +372,8 @@ static unsigned int dec10_setclrf(DisasContext *dc)
|
||||
if (set) {
|
||||
tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
|
||||
} else {
|
||||
tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
|
||||
tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
|
||||
~(flags|F_FLAG_V10|P_FLAG_V10));
|
||||
}
|
||||
|
||||
dc->flags_uptodate = 1;
|
||||
@@ -723,7 +783,7 @@ static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
|
||||
LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
|
||||
addr = tcg_temp_new();
|
||||
crisv10_prepare_memaddr(dc, addr, size);
|
||||
gen_store(dc, addr, cpu_R[dc->dst], size);
|
||||
gen_store_v10(dc, addr, cpu_R[dc->dst], size);
|
||||
insn_len += crisv10_post_memaddr(dc, size);
|
||||
|
||||
return insn_len;
|
||||
@@ -767,10 +827,10 @@ static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
|
||||
t0 = tcg_temp_new();
|
||||
cris_evaluate_flags(dc);
|
||||
tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
|
||||
gen_store(dc, addr, t0, size);
|
||||
gen_store_v10(dc, addr, t0, size);
|
||||
tcg_temp_free(t0);
|
||||
} else {
|
||||
gen_store(dc, addr, cpu_PR[dc->dst], size);
|
||||
gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
|
||||
}
|
||||
t0 = tcg_temp_new();
|
||||
insn_len += crisv10_post_memaddr(dc, size);
|
||||
@@ -793,9 +853,9 @@ static void dec10_movem_r_m(DisasContext *dc)
|
||||
tcg_gen_mov_tl(t0, addr);
|
||||
for (i = dc->dst; i >= 0; i--) {
|
||||
if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
|
||||
gen_store(dc, addr, t0, 4);
|
||||
gen_store_v10(dc, addr, t0, 4);
|
||||
} else {
|
||||
gen_store(dc, addr, cpu_R[i], 4);
|
||||
gen_store_v10(dc, addr, cpu_R[i], 4);
|
||||
}
|
||||
tcg_gen_addi_tl(addr, addr, 4);
|
||||
}
|
||||
|
@@ -4870,20 +4870,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
|
||||
tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
|
||||
gen_extu(ot, t2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
|
||||
label2 = gen_new_label();
|
||||
if (mod == 3) {
|
||||
label2 = gen_new_label();
|
||||
gen_op_mov_reg_v(ot, R_EAX, t0);
|
||||
tcg_gen_br(label2);
|
||||
gen_set_label(label1);
|
||||
gen_op_mov_reg_v(ot, rm, t1);
|
||||
gen_set_label(label2);
|
||||
} else {
|
||||
tcg_gen_mov_tl(t1, t0);
|
||||
/* perform no-op store cycle like physical cpu; must be
|
||||
before changing accumulator to ensure idempotency if
|
||||
the store faults and the instruction is restarted */
|
||||
gen_op_st_v(ot + s->mem_index, t0, a0);
|
||||
gen_op_mov_reg_v(ot, R_EAX, t0);
|
||||
tcg_gen_br(label2);
|
||||
gen_set_label(label1);
|
||||
/* always store */
|
||||
gen_op_st_v(ot + s->mem_index, t1, a0);
|
||||
}
|
||||
gen_set_label(label2);
|
||||
tcg_gen_mov_tl(cpu_cc_src, t0);
|
||||
tcg_gen_mov_tl(cpu_cc_dst, t2);
|
||||
s->cc_op = CC_OP_SUBB + ot;
|
||||
|
@@ -436,6 +436,7 @@ static inline int opsize_bytes(int opsize)
|
||||
qemu_assert(0, "bad operand size");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assign value to a register. If the width is less than the register width
|
||||
|
@@ -504,7 +504,7 @@ void kvm_arch_post_run(CPUState *env, struct kvm_run *run)
|
||||
|
||||
int kvm_arch_process_async_events(CPUState *env)
|
||||
{
|
||||
return 0;
|
||||
return env->halted;
|
||||
}
|
||||
|
||||
static int kvmppc_handle_halt(CPUState *env)
|
||||
@@ -745,7 +745,7 @@ void kvmppc_set_papr(CPUState *env)
|
||||
ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap);
|
||||
|
||||
if (ret) {
|
||||
goto fail;
|
||||
fprintf(stderr, "You're running a very old kernel. Expect breakage!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -759,7 +759,10 @@ void kvmppc_set_papr(CPUState *env)
|
||||
reg.u.reg64 = env->spr[SPR_HIOR];
|
||||
ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, ®);
|
||||
if (ret) {
|
||||
goto fail;
|
||||
fprintf(stderr, "Couldn't set HIOR. Maybe you're running an old \n"
|
||||
"kernel with support for HV KVM but no PAPR PR \n"
|
||||
"KVM in which case things will work. If they don't \n"
|
||||
"please update your host kernel!\n");
|
||||
}
|
||||
|
||||
/* Set SDR1 so kernel space finds the HTAB */
|
||||
@@ -838,12 +841,18 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
|
||||
int fd;
|
||||
void *table;
|
||||
|
||||
/* Must set fd to -1 so we don't try to munmap when called for
|
||||
* destroying the table, which the upper layers -will- do
|
||||
*/
|
||||
*pfd = -1;
|
||||
if (!cap_spapr_tce) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
|
||||
liobn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -852,6 +861,8 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
|
||||
|
||||
table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (table == MAP_FAILED) {
|
||||
fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n",
|
||||
liobn);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
@@ -871,8 +882,8 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
|
||||
len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE);
|
||||
if ((munmap(table, len) < 0) ||
|
||||
(close(fd) < 0)) {
|
||||
fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE "
|
||||
"table: %s", strerror(errno));
|
||||
fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
|
||||
strerror(errno));
|
||||
/* Leak the table */
|
||||
}
|
||||
|
||||
|
@@ -185,9 +185,6 @@ void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
|
||||
return;
|
||||
}
|
||||
|
||||
s390_add_running_cpu(env);
|
||||
qemu_cpu_kick(env);
|
||||
|
||||
kvmint.type = type;
|
||||
kvmint.parm = parm;
|
||||
kvmint.parm64 = parm64;
|
||||
|
@@ -636,6 +636,9 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
|
||||
case 0x700:
|
||||
cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
|
||||
break;
|
||||
case 0xc00:
|
||||
helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
|
||||
break;
|
||||
default:
|
||||
goto abort;
|
||||
break;
|
||||
|
@@ -1652,18 +1652,10 @@ static void _decode_opc(DisasContext * ctx)
|
||||
}
|
||||
return;
|
||||
case 0x00a3: /* ocbp @Rn */
|
||||
{
|
||||
TCGv dummy = tcg_temp_new();
|
||||
tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
|
||||
tcg_temp_free(dummy);
|
||||
}
|
||||
return;
|
||||
case 0x00b3: /* ocbwb @Rn */
|
||||
{
|
||||
TCGv dummy = tcg_temp_new();
|
||||
tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
|
||||
tcg_temp_free(dummy);
|
||||
}
|
||||
/* These instructions are supposed to do nothing in case of
|
||||
a cache miss. Given that we only partially emulate caches
|
||||
it is safe to simply ignore them. */
|
||||
return;
|
||||
case 0x0083: /* pref @Rn */
|
||||
return;
|
||||
|
49
thunk.c
49
thunk.c
@@ -41,11 +41,13 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
|
||||
case TYPE_CHAR:
|
||||
case TYPE_SHORT:
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
case TYPE_LONG:
|
||||
case TYPE_ULONG:
|
||||
case TYPE_PTRVOID:
|
||||
case TYPE_OLDDEVT:
|
||||
return type_ptr;
|
||||
case TYPE_PTR:
|
||||
return thunk_type_next_ptr(type_ptr);
|
||||
@@ -139,6 +141,26 @@ const argtype *thunk_convert(void *dst, const void *src,
|
||||
case TYPE_INT:
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
break;
|
||||
case TYPE_INTBITFIELD:
|
||||
#if defined(TARGET_I386) && defined(__powerpc__)
|
||||
/* powerpc uses the MSB, whereas i386 uses the LSB
|
||||
* to store the first bit in a field */
|
||||
{
|
||||
unsigned char byte = *(uint8_t *)src;
|
||||
*(uint8_t *)dst = ((byte >> 7) & 1)
|
||||
| ((byte >> 5) & 2)
|
||||
| ((byte >> 3) & 4)
|
||||
| ((byte >> 1) & 8)
|
||||
| ((byte << 1) & 16)
|
||||
| ((byte << 3) & 32)
|
||||
| ((byte << 5) & 64)
|
||||
| ((byte << 7) & 128);
|
||||
/* FIXME: implement for bitfields > 1 byte and other archs */
|
||||
}
|
||||
#else
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
#endif
|
||||
break;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
*(uint64_t *)dst = tswap64(*(uint64_t *)src);
|
||||
@@ -188,6 +210,33 @@ const argtype *thunk_convert(void *dst, const void *src,
|
||||
#else
|
||||
#warning unsupported conversion
|
||||
#endif
|
||||
case TYPE_OLDDEVT:
|
||||
{
|
||||
uint64_t val = 0;
|
||||
switch (thunk_type_size(type_ptr - 1, !to_host)) {
|
||||
case 2:
|
||||
val = *(uint16_t *)src;
|
||||
break;
|
||||
case 4:
|
||||
val = *(uint32_t *)src;
|
||||
break;
|
||||
case 8:
|
||||
val = *(uint64_t *)src;
|
||||
break;
|
||||
}
|
||||
switch (thunk_type_size(type_ptr - 1, to_host)) {
|
||||
case 2:
|
||||
*(uint16_t *)dst = tswap16(val);
|
||||
break;
|
||||
case 4:
|
||||
*(uint32_t *)dst = tswap32(val);
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t *)dst = tswap64(val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_ARRAY:
|
||||
{
|
||||
int array_length, i, dst_size, src_size;
|
||||
|
31
thunk.h
31
thunk.h
@@ -37,6 +37,8 @@ typedef enum argtype {
|
||||
TYPE_PTR,
|
||||
TYPE_ARRAY,
|
||||
TYPE_STRUCT,
|
||||
TYPE_INTBITFIELD,
|
||||
TYPE_OLDDEVT,
|
||||
} argtype;
|
||||
|
||||
#define MK_PTR(type) TYPE_PTR, type
|
||||
@@ -90,6 +92,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
@@ -104,6 +107,31 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||
return TARGET_ABI_BITS / 8;
|
||||
}
|
||||
break;
|
||||
case TYPE_OLDDEVT:
|
||||
if (is_host) {
|
||||
#if defined(HOST_X86_64)
|
||||
return 8;
|
||||
#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
|
||||
defined(HOST_PARISC) || defined(HOST_SPARC64)
|
||||
return 4;
|
||||
#elif defined(HOST_PPC)
|
||||
return HOST_LONG_SIZE;
|
||||
#else
|
||||
return 2;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(TARGET_X86_64)
|
||||
return 8;
|
||||
#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
|
||||
defined(TARGET_PARISC) || defined(TARGET_SPARC64)
|
||||
return 4;
|
||||
#elif defined(TARGET_PPC)
|
||||
return TARGET_ABI_BITS / 8;
|
||||
#else
|
||||
return 2;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TYPE_ARRAY:
|
||||
size = type_ptr[1];
|
||||
return size * thunk_type_size_array(type_ptr + 2, is_host);
|
||||
@@ -127,6 +155,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
@@ -141,6 +170,8 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
|
||||
return TARGET_ABI_BITS / 8;
|
||||
}
|
||||
break;
|
||||
case TYPE_OLDDEVT:
|
||||
return thunk_type_size(type_ptr, is_host);
|
||||
case TYPE_ARRAY:
|
||||
return thunk_type_align_array(type_ptr + 2, is_host);
|
||||
case TYPE_STRUCT:
|
||||
|
@@ -579,11 +579,11 @@ v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode
|
||||
v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
|
||||
v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
|
||||
v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
|
||||
v9fs_read(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t max_count) "tag %d id %d fid %d off %"PRId64" max_count %d"
|
||||
v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
|
||||
v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
|
||||
v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, int64_t offset, int32_t max_count) "tag %d id %d fid %d offset %"PRId64" max_count %d"
|
||||
v9fs_readdir_return(uint16_t tag, uint8_t id, int32_t count, ssize_t retval) "tag %d id %d count %d retval %zd"
|
||||
v9fs_write(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t count, int cnt) "tag %d id %d fid %d off %"PRId64" count %d cnt %d"
|
||||
v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
|
||||
v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
|
||||
v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
|
||||
v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
|
||||
v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
|
||||
v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
|
||||
|
47
usb-linux.c
47
usb-linux.c
@@ -116,6 +116,7 @@ typedef struct USBHostDevice {
|
||||
USBDevice dev;
|
||||
int fd;
|
||||
int hub_fd;
|
||||
int hub_port;
|
||||
|
||||
uint8_t descr[8192];
|
||||
int descr_len;
|
||||
@@ -434,7 +435,7 @@ static int usb_host_claim_port(USBHostDevice *s)
|
||||
{
|
||||
#ifdef USBDEVFS_CLAIM_PORT
|
||||
char *h, hub_name[64], line[1024];
|
||||
int hub_addr, portnr, ret;
|
||||
int hub_addr, ret;
|
||||
|
||||
snprintf(hub_name, sizeof(hub_name), "%d-%s",
|
||||
s->match.bus_num, s->match.port);
|
||||
@@ -442,13 +443,13 @@ static int usb_host_claim_port(USBHostDevice *s)
|
||||
/* try strip off last ".$portnr" to get hub */
|
||||
h = strrchr(hub_name, '.');
|
||||
if (h != NULL) {
|
||||
portnr = atoi(h+1);
|
||||
s->hub_port = atoi(h+1);
|
||||
*h = '\0';
|
||||
} else {
|
||||
/* no dot in there -> it is the root hub */
|
||||
snprintf(hub_name, sizeof(hub_name), "usb%d",
|
||||
s->match.bus_num);
|
||||
portnr = atoi(s->match.port);
|
||||
s->hub_port = atoi(s->match.port);
|
||||
}
|
||||
|
||||
if (!usb_host_read_file(line, sizeof(line), "devnum",
|
||||
@@ -469,20 +470,32 @@ static int usb_host_claim_port(USBHostDevice *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr);
|
||||
ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &s->hub_port);
|
||||
if (ret < 0) {
|
||||
close(s->hub_fd);
|
||||
s->hub_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr);
|
||||
trace_usb_host_claim_port(s->match.bus_num, hub_addr, s->hub_port);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usb_host_release_port(USBHostDevice *s)
|
||||
{
|
||||
if (s->hub_fd == -1) {
|
||||
return;
|
||||
}
|
||||
#ifdef USBDEVFS_RELEASE_PORT
|
||||
ioctl(s->hub_fd, USBDEVFS_RELEASE_PORT, &s->hub_port);
|
||||
#endif
|
||||
close(s->hub_fd);
|
||||
s->hub_fd = -1;
|
||||
}
|
||||
|
||||
static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
|
||||
{
|
||||
/* earlier Linux 2.4 do not support that */
|
||||
@@ -635,10 +648,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
|
||||
{
|
||||
USBHostDevice *s = (USBHostDevice *)dev;
|
||||
|
||||
usb_host_release_port(s);
|
||||
usb_host_close(s);
|
||||
if (s->hub_fd != -1) {
|
||||
close(s->hub_fd);
|
||||
}
|
||||
QTAILQ_REMOVE(&hostdevs, s, next);
|
||||
qemu_remove_exit_notifier(&s->exit);
|
||||
}
|
||||
@@ -1141,15 +1152,18 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
|
||||
length = s->descr_len - 18;
|
||||
i = 0;
|
||||
|
||||
if (descriptors[i + 1] != USB_DT_CONFIG ||
|
||||
descriptors[i + 5] != s->configuration) {
|
||||
fprintf(stderr, "invalid descriptor data - configuration %d\n",
|
||||
s->configuration);
|
||||
return 1;
|
||||
}
|
||||
i += descriptors[i];
|
||||
|
||||
while (i < length) {
|
||||
if (descriptors[i + 1] != USB_DT_CONFIG) {
|
||||
fprintf(stderr, "invalid descriptor data\n");
|
||||
return 1;
|
||||
} else if (descriptors[i + 5] != s->configuration) {
|
||||
DPRINTF("not requested configuration %d\n", s->configuration);
|
||||
i += (descriptors[i + 3] << 8) + descriptors[i + 2];
|
||||
continue;
|
||||
}
|
||||
|
||||
i += descriptors[i];
|
||||
|
||||
if (descriptors[i + 1] != USB_DT_INTERFACE ||
|
||||
(descriptors[i + 1] == USB_DT_INTERFACE &&
|
||||
descriptors[i + 4] == 0)) {
|
||||
@@ -1399,6 +1413,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
|
||||
{
|
||||
USBHostDevice *s = container_of(n, USBHostDevice, exit);
|
||||
|
||||
usb_host_release_port(s);
|
||||
if (s->fd != -1) {
|
||||
usb_host_do_reset(s);;
|
||||
}
|
||||
|
@@ -96,6 +96,10 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
|
||||
qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
|
||||
pc, address, is_write, *(unsigned long *)old_set);
|
||||
#endif
|
||||
|
||||
/* Maybe we're still holding the TB fiddling lock? */
|
||||
spin_unlock_safe(&tb_lock);
|
||||
|
||||
/* XXX: locking issue */
|
||||
if (is_write && page_unprotect(h2g(address), pc, puc)) {
|
||||
return 1;
|
||||
|
5
vl.c
5
vl.c
@@ -174,6 +174,8 @@ int main(int argc, char **argv)
|
||||
|
||||
#define MAX_VIRTIO_CONSOLES 1
|
||||
|
||||
extern int use_stopflag;
|
||||
|
||||
static const char *data_dir;
|
||||
const char *bios_name = NULL;
|
||||
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
|
||||
@@ -2819,6 +2821,9 @@ int main(int argc, char **argv, char **envp)
|
||||
case QEMU_OPTION_rtc_td_hack:
|
||||
rtc_td_hack = 1;
|
||||
break;
|
||||
case QEMU_OPTION_no_stopflag:
|
||||
use_stopflag = 0;
|
||||
break;
|
||||
case QEMU_OPTION_acpitable:
|
||||
do_acpitable_option(optarg);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user