diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/block/block.h | 19 | ||||
-rw-r--r-- | include/block/block_int.h | 7 | ||||
-rw-r--r-- | include/block/blockjob.h | 14 | ||||
-rw-r--r-- | include/block/qapi.h | 2 | ||||
-rw-r--r-- | include/exec/cpu-defs.h | 2 | ||||
-rw-r--r-- | include/exec/def-helper.h | 3 | ||||
-rw-r--r-- | include/exec/exec-all.h | 30 | ||||
-rw-r--r-- | include/exec/softmmu_template.h | 286 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 8 | ||||
-rw-r--r-- | include/hw/qdev-core.h | 16 | ||||
-rw-r--r-- | include/qemu/option.h | 1 | ||||
-rw-r--r-- | include/sysemu/blockdev.h | 1 | ||||
-rw-r--r-- | include/sysemu/char.h | 1 |
13 files changed, 298 insertions, 92 deletions
diff --git a/include/block/block.h b/include/block/block.h index f808550..3560deb 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -84,6 +84,9 @@ typedef struct BlockDevOps { /* BDRV_BLOCK_DATA: data is read from bs->file or another file * BDRV_BLOCK_ZERO: sectors read as zero * BDRV_BLOCK_OFFSET_VALID: sector stored in bs->file as raw data + * BDRV_BLOCK_RAW: used internally to indicate that the request + * was answered by the raw driver and that one + * should look in bs->file directly. * * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 represent the offset in * bs->file where sector data can be read from as raw data. @@ -105,6 +108,7 @@ typedef struct BlockDevOps { #define BDRV_BLOCK_DATA 1 #define BDRV_BLOCK_ZERO 2 #define BDRV_BLOCK_OFFSET_VALID 4 +#define BDRV_BLOCK_RAW 8 #define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK typedef enum { @@ -244,6 +248,20 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options); +/* external snapshots */ + +typedef enum { + EXT_SNAPSHOT_ALLOWED, + EXT_SNAPSHOT_FORBIDDEN, +} ExtSnapshotPerm; + +/* return EXT_SNAPSHOT_ALLOWED if external snapshot is allowed + * return EXT_SNAPSHOT_FORBIDDEN if external snapshot is forbidden + */ +ExtSnapshotPerm bdrv_check_ext_snapshot(BlockDriverState *bs); +/* helper used to forbid external snapshots like in blkverify */ +ExtSnapshotPerm bdrv_check_ext_snapshot_forbidden(BlockDriverState *bs); + /* async block I/O */ typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector, int sector_num); @@ -335,6 +353,7 @@ int bdrv_get_flags(BlockDriverState *bs); int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); +ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs); void bdrv_round_to_clusters(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int64_t *cluster_sector_num, diff --git a/include/block/block_int.h b/include/block/block_int.h index 211087a..a48731d 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -67,6 +67,12 @@ typedef struct BdrvTrackedRequest { struct BlockDriver { const char *format_name; int instance_size; + + /* if not defined external snapshots are allowed + * future block filters will query their children to build the response + */ + ExtSnapshotPerm (*bdrv_check_ext_snapshot)(BlockDriverState *bs); + int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); int (*bdrv_probe_device)(const char *filename); @@ -168,6 +174,7 @@ struct BlockDriver { int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs, const char *snapshot_name); int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); + ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs); int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); diff --git a/include/block/blockjob.h b/include/block/blockjob.h index d530409..d76de62 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -28,16 +28,16 @@ #include "block/block.h" /** - * BlockJobType: + * BlockJobDriver: * - * A class type for block job objects. + * A class type for block job driver. */ -typedef struct BlockJobType { +typedef struct BlockJobDriver { /** Derived BlockJob struct size */ size_t instance_size; /** String describing the operation, part of query-block-jobs QMP API */ - const char *job_type; + BlockJobType job_type; /** Optional callback for job types that support setting a speed limit */ void (*set_speed)(BlockJob *job, int64_t speed, Error **errp); @@ -50,7 +50,7 @@ typedef struct BlockJobType { * manually. */ void (*complete)(BlockJob *job, Error **errp); -} BlockJobType; +} BlockJobDriver; /** * BlockJob: @@ -59,7 +59,7 @@ typedef struct BlockJobType { */ struct BlockJob { /** The job type, including the job vtable. */ - const BlockJobType *job_type; + const BlockJobDriver *driver; /** The block device on which the job is operating. */ BlockDriverState *bs; @@ -128,7 +128,7 @@ struct BlockJob { * This function is not part of the public job interface; it should be * called from a wrapper that is specific to the job type. */ -void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, +void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs, int64_t speed, BlockDriverCompletionFunc *cb, void *opaque, Error **errp); diff --git a/include/block/qapi.h b/include/block/qapi.h index 0496cc9..9518ee4 100644 --- a/include/block/qapi.h +++ b/include/block/qapi.h @@ -42,6 +42,8 @@ BlockStats *bdrv_query_stats(const BlockDriverState *bs); void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, QEMUSnapshotInfo *sn); +void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f, + ImageInfoSpecific *info_spec); void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, ImageInfo *info); #endif diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index a5c028c..01cd8c7 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -178,7 +178,5 @@ typedef struct CPUWatchpoint { \ /* user data */ \ void *opaque; \ - \ - const char *cpu_model_str; #endif diff --git a/include/exec/def-helper.h b/include/exec/def-helper.h index 022a9ce..73d51f9 100644 --- a/include/exec/def-helper.h +++ b/include/exec/def-helper.h @@ -240,8 +240,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \ #elif GEN_HELPER == 2 /* Register helpers. */ -#define DEF_HELPER_FLAGS_0(name, flags, ret) \ -tcg_register_helper(HELPER(name), #name); +#define DEF_HELPER_FLAGS_0(name, flags, ret) { HELPER(name), #name }, #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ DEF_HELPER_FLAGS_0(name, flags, ret) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8dd1594..6ad05ca 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -320,36 +320,6 @@ extern uintptr_t tci_tb_ptr; #define GETPC() (GETRA() - GETPC_ADJ) -/* The LDST optimizations splits code generation into fast and slow path. - In some implementations, we pass the "logical" return address manually; - in others, we must infer the logical return from the true return. */ -#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) -# if defined(__aarch64__) -# define GETRA_LDST(RA) tcg_getra_ldst(RA) -static inline uintptr_t tcg_getra_ldst(uintptr_t ra) -{ - int32_t b; - ra += 4; /* skip one instruction */ - b = *(int32_t *)ra; /* load the branch insn */ - b = (b << 6) >> (6 - 2); /* extract the displacement */ - ra += b; /* apply the displacement */ - return ra; -} -# endif -#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */ - -/* ??? Delete these once they are no longer used. */ -bool is_tcg_gen_code(uintptr_t pc_ptr); -#ifdef GETRA_LDST -# define GETRA_EXT() tcg_getra_ext(GETRA()) -static inline uintptr_t tcg_getra_ext(uintptr_t ra) -{ - return is_tcg_gen_code(ra) ? GETRA_LDST(ra) : ra; -} -#else -# define GETRA_EXT() GETRA() -#endif - #if !defined(CONFIG_USER_ONLY) void phys_mem_set_alloc(void *(*alloc)(ram_addr_t)); diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h index 5bbc56a..c6a5440 100644 --- a/include/exec/softmmu_template.h +++ b/include/exec/softmmu_template.h @@ -70,6 +70,48 @@ #define ADDR_READ addr_read #endif +#if DATA_SIZE == 8 +# define BSWAP(X) bswap64(X) +#elif DATA_SIZE == 4 +# define BSWAP(X) bswap32(X) +#elif DATA_SIZE == 2 +# define BSWAP(X) bswap16(X) +#else +# define BSWAP(X) (X) +#endif + +#ifdef TARGET_WORDS_BIGENDIAN +# define TGT_BE(X) (X) +# define TGT_LE(X) BSWAP(X) +#else +# define TGT_BE(X) BSWAP(X) +# define TGT_LE(X) (X) +#endif + +#if DATA_SIZE == 1 +# define helper_le_ld_name glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) +# define helper_be_ld_name helper_le_ld_name +# define helper_le_lds_name glue(glue(helper_ret_ld, SSUFFIX), MMUSUFFIX) +# define helper_be_lds_name helper_le_lds_name +# define helper_le_st_name glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX) +# define helper_be_st_name helper_le_st_name +#else +# define helper_le_ld_name glue(glue(helper_le_ld, USUFFIX), MMUSUFFIX) +# define helper_be_ld_name glue(glue(helper_be_ld, USUFFIX), MMUSUFFIX) +# define helper_le_lds_name glue(glue(helper_le_ld, SSUFFIX), MMUSUFFIX) +# define helper_be_lds_name glue(glue(helper_be_ld, SSUFFIX), MMUSUFFIX) +# define helper_le_st_name glue(glue(helper_le_st, SUFFIX), MMUSUFFIX) +# define helper_be_st_name glue(glue(helper_be_st, SUFFIX), MMUSUFFIX) +#endif + +#ifdef TARGET_WORDS_BIGENDIAN +# define helper_te_ld_name helper_be_ld_name +# define helper_te_st_name helper_be_st_name +#else +# define helper_te_ld_name helper_le_ld_name +# define helper_te_st_name helper_le_st_name +#endif + static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, hwaddr physaddr, target_ulong addr, @@ -89,18 +131,16 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, return val; } -/* handle all cases except unaligned access which span two pages */ #ifdef SOFTMMU_CODE_ACCESS -static +static __attribute__((unused)) #endif -WORD_TYPE -glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, - target_ulong addr, int mmu_idx, - uintptr_t retaddr) +WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, + uintptr_t retaddr) { int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; uintptr_t haddr; + DATA_TYPE res; /* Adjust the given return address. */ retaddr -= GETPC_ADJ; @@ -124,7 +164,12 @@ glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, goto do_unaligned_access; } ioaddr = env->iotlb[mmu_idx][index]; - return glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr); + + /* ??? Note that the io helpers always read data in the target + byte ordering. We should push the LE/BE request down into io. */ + res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr); + res = TGT_LE(res); + return res; } /* Handle slow unaligned access (it spans two pages or IO). */ @@ -132,7 +177,7 @@ glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 >= TARGET_PAGE_SIZE)) { target_ulong addr1, addr2; - DATA_TYPE res1, res2, res; + DATA_TYPE res1, res2; unsigned shift; do_unaligned_access: #ifdef ALIGNED_ONLY @@ -142,16 +187,94 @@ glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, addr2 = addr1 + DATA_SIZE; /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ - res1 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) - (env, addr1, mmu_idx, retaddr + GETPC_ADJ); - res2 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) - (env, addr2, mmu_idx, retaddr + GETPC_ADJ); + res1 = helper_le_ld_name(env, addr1, mmu_idx, retaddr + GETPC_ADJ); + res2 = helper_le_ld_name(env, addr2, mmu_idx, retaddr + GETPC_ADJ); shift = (addr & (DATA_SIZE - 1)) * 8; -#ifdef TARGET_WORDS_BIGENDIAN - res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); -#else + + /* Little-endian combine. */ res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift)); + return res; + } + + /* Handle aligned access or unaligned access in the same page. */ +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + } +#endif + + haddr = addr + env->tlb_table[mmu_idx][index].addend; +#if DATA_SIZE == 1 + res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr); +#else + res = glue(glue(ld, LSUFFIX), _le_p)((uint8_t *)haddr); +#endif + return res; +} + +#if DATA_SIZE > 1 +#ifdef SOFTMMU_CODE_ACCESS +static __attribute__((unused)) +#endif +WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx, + uintptr_t retaddr) +{ + int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; + uintptr_t haddr; + DATA_TYPE res; + + /* Adjust the given return address. */ + retaddr -= GETPC_ADJ; + + /* If the TLB entry is for a different page, reload and try again. */ + if ((addr & TARGET_PAGE_MASK) + != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + } +#endif + tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; + } + + /* Handle an IO access. */ + if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { + hwaddr ioaddr; + if ((addr & (DATA_SIZE - 1)) != 0) { + goto do_unaligned_access; + } + ioaddr = env->iotlb[mmu_idx][index]; + + /* ??? Note that the io helpers always read data in the target + byte ordering. We should push the LE/BE request down into io. */ + res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr); + res = TGT_BE(res); + return res; + } + + /* Handle slow unaligned access (it spans two pages or IO). */ + if (DATA_SIZE > 1 + && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 + >= TARGET_PAGE_SIZE)) { + target_ulong addr1, addr2; + DATA_TYPE res1, res2; + unsigned shift; + do_unaligned_access: +#ifdef ALIGNED_ONLY + do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif + addr1 = addr & ~(DATA_SIZE - 1); + addr2 = addr1 + DATA_SIZE; + /* Note the adjustment at the beginning of the function. + Undo that for the recursion. */ + res1 = helper_be_ld_name(env, addr1, mmu_idx, retaddr + GETPC_ADJ); + res2 = helper_be_ld_name(env, addr2, mmu_idx, retaddr + GETPC_ADJ); + shift = (addr & (DATA_SIZE - 1)) * 8; + + /* Big-endian combine. */ + res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); return res; } @@ -163,16 +286,16 @@ glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env, #endif haddr = addr + env->tlb_table[mmu_idx][index].addend; - /* Note that ldl_raw is defined with type "int". */ - return (DATA_TYPE) glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr); + res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr); + return res; } +#endif /* DATA_SIZE > 1 */ DATA_TYPE glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, int mmu_idx) { - return glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(env, addr, mmu_idx, - GETRA_EXT()); + return helper_te_ld_name (env, addr, mmu_idx, GETRA()); } #ifndef SOFTMMU_CODE_ACCESS @@ -180,14 +303,19 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, /* Provide signed versions of the load routines as well. We can of course avoid this for 64-bit data, or for 32-bit data on 32-bit host. */ #if DATA_SIZE * 8 < TCG_TARGET_REG_BITS -WORD_TYPE -glue(glue(helper_ret_ld, SSUFFIX), MMUSUFFIX)(CPUArchState *env, - target_ulong addr, int mmu_idx, - uintptr_t retaddr) +WORD_TYPE helper_le_lds_name(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr) +{ + return (SDATA_TYPE)helper_le_ld_name(env, addr, mmu_idx, retaddr); +} + +# if DATA_SIZE > 1 +WORD_TYPE helper_be_lds_name(CPUArchState *env, target_ulong addr, + int mmu_idx, uintptr_t retaddr) { - return (SDATA_TYPE) glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX) - (env, addr, mmu_idx, retaddr); + return (SDATA_TYPE)helper_be_ld_name(env, addr, mmu_idx, retaddr); } +# endif #endif static inline void glue(io_write, SUFFIX)(CPUArchState *env, @@ -208,10 +336,8 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, io_mem_write(mr, physaddr, val, 1 << SHIFT); } -void -glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, - target_ulong addr, DATA_TYPE val, - int mmu_idx, uintptr_t retaddr) +void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, + int mmu_idx, uintptr_t retaddr) { int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; @@ -239,6 +365,10 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, goto do_unaligned_access; } ioaddr = env->iotlb[mmu_idx][index]; + + /* ??? Note that the io helpers always read data in the target + byte ordering. We should push the LE/BE request down into io. */ + val = TGT_LE(val); glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr); return; } @@ -256,11 +386,84 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, /* Note: relies on the fact that tlb_fill() does not remove the * previous page from the TLB cache. */ for (i = DATA_SIZE - 1; i >= 0; i--) { -#ifdef TARGET_WORDS_BIGENDIAN - uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8)); -#else + /* Little-endian extract. */ uint8_t val8 = val >> (i * 8); + /* Note the adjustment at the beginning of the function. + Undo that for the recursion. */ + glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, + mmu_idx, retaddr + GETPC_ADJ); + } + return; + } + + /* Handle aligned access or unaligned access in the same page. */ +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + do_unaligned_access(env, addr, 1, mmu_idx, retaddr); + } +#endif + + haddr = addr + env->tlb_table[mmu_idx][index].addend; +#if DATA_SIZE == 1 + glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val); +#else + glue(glue(st, SUFFIX), _le_p)((uint8_t *)haddr, val); #endif +} + +#if DATA_SIZE > 1 +void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, + int mmu_idx, uintptr_t retaddr) +{ + int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; + uintptr_t haddr; + + /* Adjust the given return address. */ + retaddr -= GETPC_ADJ; + + /* If the TLB entry is for a different page, reload and try again. */ + if ((addr & TARGET_PAGE_MASK) + != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + do_unaligned_access(env, addr, 1, mmu_idx, retaddr); + } +#endif + tlb_fill(env, addr, 1, mmu_idx, retaddr); + tlb_addr = env->tlb_table[mmu_idx][index].addr_write; + } + + /* Handle an IO access. */ + if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { + hwaddr ioaddr; + if ((addr & (DATA_SIZE - 1)) != 0) { + goto do_unaligned_access; + } + ioaddr = env->iotlb[mmu_idx][index]; + + /* ??? Note that the io helpers always read data in the target + byte ordering. We should push the LE/BE request down into io. */ + val = TGT_BE(val); + glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr); + return; + } + + /* Handle slow unaligned access (it spans two pages or IO). */ + if (DATA_SIZE > 1 + && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 + >= TARGET_PAGE_SIZE)) { + int i; + do_unaligned_access: +#ifdef ALIGNED_ONLY + do_unaligned_access(env, addr, 1, mmu_idx, retaddr); +#endif + /* XXX: not efficient, but simple */ + /* Note: relies on the fact that tlb_fill() does not remove the + * previous page from the TLB cache. */ + for (i = DATA_SIZE - 1; i >= 0; i--) { + /* Big-endian extract. */ + uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8)); /* Note the adjustment at the beginning of the function. Undo that for the recursion. */ glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, @@ -277,15 +480,15 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, #endif haddr = addr + env->tlb_table[mmu_idx][index].addend; - glue(glue(st, SUFFIX), _raw)((uint8_t *)haddr, val); + glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val); } +#endif /* DATA_SIZE > 1 */ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, DATA_TYPE val, int mmu_idx) { - glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx, - GETRA_EXT()); + helper_te_st_name(env, addr, val, mmu_idx, GETRA()); } #endif /* !defined(SOFTMMU_CODE_ACCESS) */ @@ -301,3 +504,16 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, #undef SDATA_TYPE #undef USUFFIX #undef SSUFFIX +#undef BSWAP +#undef TGT_BE +#undef TGT_LE +#undef CPU_BE +#undef CPU_LE +#undef helper_le_ld_name +#undef helper_be_ld_name +#undef helper_le_lds_name +#undef helper_be_lds_name +#undef helper_le_st_name +#undef helper_be_st_name +#undef helper_te_ld_name +#undef helper_te_st_name diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9b2ddc4..6083839 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -230,6 +230,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = "e1000",\ .property = "mitigation",\ .value = "off",\ + },{\ + .driver = "qemu64-" TYPE_X86_CPU,\ + .property = "model",\ + .value = stringify(2),\ + },{\ + .driver = "qemu32-" TYPE_X86_CPU,\ + .property = "model",\ + .value = stringify(3),\ } #define PC_COMPAT_1_5 \ diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index a62f231..e191ca0 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -30,22 +30,6 @@ typedef enum DeviceCategory { DEVICE_CATEGORY_MAX } DeviceCategory; -static inline const char *qdev_category_get_name(DeviceCategory category) -{ - static const char *category_names[DEVICE_CATEGORY_MAX] = { - [DEVICE_CATEGORY_BRIDGE] = "Controller/Bridge/Hub", - [DEVICE_CATEGORY_USB] = "USB", - [DEVICE_CATEGORY_STORAGE] = "Storage", - [DEVICE_CATEGORY_NETWORK] = "Network", - [DEVICE_CATEGORY_INPUT] = "Input", - [DEVICE_CATEGORY_DISPLAY] = "Display", - [DEVICE_CATEGORY_SOUND] = "Sound", - [DEVICE_CATEGORY_MISC] = "Misc", - }; - - return category_names[category]; -}; - typedef int (*qdev_initfn)(DeviceState *dev); typedef int (*qdev_event)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev); diff --git a/include/qemu/option.h b/include/qemu/option.h index 63db4cc..5c0c6dd 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -142,6 +142,7 @@ void qemu_opts_loc_restore(QemuOpts *opts); int qemu_opts_set(QemuOptsList *list, const char *id, const char *name, const char *value); const char *qemu_opts_id(QemuOpts *opts); +void qemu_opts_set_id(QemuOpts *opts, char *id); void qemu_opts_del(QemuOpts *opts); void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp); int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname); diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 804ec88..1082091 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -37,6 +37,7 @@ struct DriveInfo { int bus; int unit; int auto_del; /* see blockdev_mark_auto_del() */ + bool enable_auto_del; /* Only for legacy drive_init() */ int media_cd; int cyls, heads, secs, trans; QemuOpts *opts; diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 8053130..ad101d9 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -78,6 +78,7 @@ struct CharDriverState { int explicit_be_open; int avail_connections; int is_mux; + guint fd_in_tag; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; |