This commit is contained in:
2026-07-20 18:00:59 -04:00
parent 42c96a31a2
commit 1a782eef9e
4 changed files with 279 additions and 43 deletions
+191 -24
View File
@@ -303,7 +303,7 @@ index 90fa54352c..0fa9cc31b6 100644
/*
* parse_zone - Fill a zone descriptor
diff --git c/block/vvfat.c w/block/vvfat.c
index 8ffe8b3b9b..4cf02d9a55 100644
index 8ffe8b3b9b..3c0ab6c228 100644
--- c/block/vvfat.c
+++ w/block/vvfat.c
@@ -749,6 +749,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
@@ -353,7 +353,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
s->directory.next < s->root_entries) {
/* root directory */
int cur = s->directory.next;
@@ -877,20 +878,24 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
@@ -877,20 +878,29 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
* 0x20 / s->cluster_size;
mapping->end = first_cluster;
@@ -370,7 +370,12 @@ index 8ffe8b3b9b..4cf02d9a55 100644
static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
{
- return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
+ return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster
+ off_t relative_sector = sector_num - s->offset_to_root_dir;
+
+ if (relative_sector < 0) {
+ return -1 - (-relative_sector - 1) / s->sectors_per_cluster;
+ }
+ return relative_sector / s->sectors_per_cluster
+ + (s->fat_type == 32 ? 2 : 0);
}
@@ -382,7 +387,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
}
static int init_directories(BDRVVVFATState* s,
@@ -934,11 +939,12 @@ static int init_directories(BDRVVVFATState* s,
@@ -934,11 +944,12 @@ static int init_directories(BDRVVVFATState* s,
init_fat(s);
/* TODO: if there are more entries, bootsector has to be adjusted! */
@@ -397,7 +402,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
mapping->dir_index = 0;
mapping->info.dir.parent_mapping_index = -1;
mapping->first_mapping_index = -1;
@@ -950,11 +956,10 @@ static int init_directories(BDRVVVFATState* s,
@@ -950,11 +961,10 @@ static int init_directories(BDRVVVFATState* s,
mapping->read_only = 0;
s->path = mapping->path;
@@ -413,7 +418,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
mapping = array_get(&(s->mapping), i);
if (mapping->mode & MODE_DIRECTORY) {
@@ -1026,22 +1031,35 @@ static int init_directories(BDRVVVFATState* s,
@@ -1026,22 +1036,35 @@ static int init_directories(BDRVVVFATState* s,
/* media descriptor: hard disk=0xf8, floppy=0xf0 */
bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
s->fat.pointer[0] = bootsector->media_type;
@@ -460,7 +465,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
return 0;
@@ -1139,6 +1157,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -1139,6 +1162,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
{
BDRVVVFATState *s = bs->opaque;
int cyls, heads, secs;
@@ -468,7 +473,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
bool floppy;
const char *dirname, *label;
QemuOpts *opts;
@@ -1205,7 +1224,9 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -1205,7 +1229,9 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
switch (s->fat_type) {
case 32:
@@ -478,7 +483,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
break;
case 16:
case 12:
@@ -1219,8 +1240,17 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -1219,8 +1245,17 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
s->bs = bs;
@@ -498,7 +503,7 @@ index 8ffe8b3b9b..4cf02d9a55 100644
s->current_cluster=0xffffffff;
@@ -1232,8 +1262,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -1232,8 +1267,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
dirname, cyls, heads, secs));
@@ -509,16 +514,123 @@ index 8ffe8b3b9b..4cf02d9a55 100644
if (qemu_opt_get_bool(opts, "rw", false)) {
if (!bdrv_is_read_only(bs)) {
@@ -1523,7 +1553,8 @@ vvfat_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sector
@@ -1259,8 +1294,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- s->sector_count = s->offset_to_root_dir
- + s->sectors_per_cluster * s->cluster_count;
+ s->sector_count = cluster2sector(s, s->cluster_count);
/* Disable migration when vvfat is used rw */
if (s->qcow) {
@@ -1415,6 +1449,7 @@ read_cluster_directory:
if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
return -3;
s->cluster=s->cluster_buffer;
+ memset(s->cluster, 0, s->cluster_size);
result=read(s->current_fd,s->cluster,s->cluster_size);
if(result<0) {
s->current_cluster = -1;
@@ -1523,8 +1558,9 @@ vvfat_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sector
} else {
uint32_t sector = sector_num - s->offset_to_root_dir,
sector_offset_in_cluster=(sector%s->sectors_per_cluster),
- cluster_num=sector/s->sectors_per_cluster;
- if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
+ cluster_num=sector/s->sectors_per_cluster
+ + (s->fat_type == 32 ? 2 : 0);
if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
+ if(cluster_num >= s->cluster_count || read_cluster(s, cluster_num) != 0) {
/* LATER TODO: strict: return -1; */
memset(buf+i*0x200,0,0x200);
continue;
@@ -1780,7 +1816,8 @@ static int parse_short_name(BDRVVVFATState* s,
static inline uint32_t modified_fat_get(BDRVVVFATState* s,
unsigned int cluster)
{
- if (cluster < s->last_cluster_of_root_directory) {
+ if (s->fat_type != 32 &&
+ cluster < s->last_cluster_of_root_directory) {
if (cluster + 1 == s->last_cluster_of_root_directory)
return s->max_fat_value;
else
@@ -2182,14 +2219,17 @@ DLOG(checkpoint());
mapping->mode |= MODE_DELETED;
}
- used_clusters_count = check_directory_consistency(s, 0, s->path);
+ mapping_t *root_mapping = array_get(&(s->mapping), 0);
+ used_clusters_count = check_directory_consistency(s,
+ root_mapping->begin, s->path);
if (used_clusters_count <= 0) {
DLOG(fprintf(stderr, "problem in directory\n"));
return 0;
}
- check = s->last_cluster_of_root_directory;
- for (i = check; i < sector2cluster(s, s->sector_count); i++) {
+ check = s->fat_type == 32 ? 0 : s->last_cluster_of_root_directory;
+ for (i = s->fat_type == 32 ? 2 : check;
+ i < sector2cluster(s, s->sector_count); i++) {
if (modified_fat_get(s, i)) {
if(!s->used_clusters[i]) {
DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
@@ -2417,7 +2457,10 @@ static int coroutine_fn GRAPH_RDLOCK
commit_direntries(BDRVVVFATState* s, int dir_index, int parent_mapping_index)
{
direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
+ bool is_root = dir_index == 0;
+ mapping_t *root_mapping = array_get(&(s->mapping), 0);
+ uint32_t first_cluster = is_root ? root_mapping->begin :
+ begin_of_direntry(direntry);
mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
int factor = 0x10 * s->sectors_per_cluster;
int old_cluster_count, new_cluster_count;
@@ -2440,7 +2483,7 @@ commit_direntries(BDRVVVFATState* s, int dir_index, int parent_mapping_index)
first_dir_index = current_dir_index;
mapping->info.dir.parent_mapping_index = parent_mapping_index;
- if (first_cluster == 0) {
+ if (is_root && s->fat_type != 32) {
old_cluster_count = new_cluster_count =
s->last_cluster_of_root_directory;
} else {
@@ -2998,11 +3041,9 @@ DLOG(checkpoint());
*/
unsigned char *bootsector = s->first_sectors
+ s->offset_to_bootsector * 0x200;
- /*
- * LATER TODO: if FAT32, this is wrong (see init_directories(),
- * which always creates a FAT16 bootsector)
- */
- const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1);
+ const int reserved1_offset = s->fat_type == 32 ?
+ offsetof(bootsector_t, u.fat32.reserved1) :
+ offsetof(bootsector_t, u.fat16.reserved1);
for (i = 0; i < 0x200; i++) {
if (i != reserved1_offset && bootsector[i] != buf[i]) {
@@ -3057,8 +3098,8 @@ DLOG(checkpoint());
begin = sector_num;
if (end > sector_num + nb_sectors)
end = sector_num + nb_sectors;
- dir_index = mapping->dir_index +
- 0x10 * (begin - mapping->begin * s->sectors_per_cluster);
+ dir_index = mapping->info.dir.first_dir_index +
+ 0x10 * (begin - cluster2sector(s, mapping->begin));
direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
for (k = 0; k < (end - begin) * 0x10; k++) {
@@ -3093,7 +3134,7 @@ DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sec
}
for (i = first_cluster; i <= last_cluster; i++) {
- if (i >= 0) {
+ if (i >= 0 && i < sector2cluster(s, s->sector_count)) {
s->used_clusters[i] |= USED_ALLOCATED;
}
}
diff --git c/configs/devices/riscv32-softmmu/xteink.mak w/configs/devices/riscv32-softmmu/xteink.mak
new file mode 100644
index 0000000000..a9179b4119
@@ -1135,6 +1247,21 @@ index c1376b7299..1275808dc0 100644
{
level_shared |= 1;
}
diff --git c/hw/sd/ssi-sd.c w/hw/sd/ssi-sd.c
index 552dc2c8ea..eb12207897 100644
--- c/hw/sd/ssi-sd.c
+++ w/hw/sd/ssi-sd.c
@@ -162,6 +162,10 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
return SSI_DUMMY;
}
+ if ((val & 0xc0) != 0x40) {
+ DPRINTF("Ignore non-command byte 0x%02x\n", val);
+ return SSI_DUMMY;
+ }
s->cmd = val & 0x3f;
s->mode = SSI_SD_CMDARG;
s->arglen = 0;
diff --git c/include/exec/exec-all.h w/include/exec/exec-all.h
index 2e4c4cc4b4..99e6da08c9 100644
--- c/include/exec/exec-all.h
@@ -1616,7 +1743,7 @@ index 478ec051c4..41895c68fa 100644
need_prot |= host_prot_read_exec();
}
diff --git c/tcg/tcg.c w/tcg/tcg.c
index 6dc3072f92..214e66e9d6 100644
index 6dc3072f92..0f6c0f5082 100644
--- c/tcg/tcg.c
+++ w/tcg/tcg.c
@@ -131,6 +131,10 @@ static void tcg_out_goto_tb(TCGContext *s, int which);
@@ -2027,7 +2154,7 @@ index 6dc3072f92..214e66e9d6 100644
#ifdef TCG_TARGET_NEED_LDST_LABELS
QSIMPLEQ_INIT(&s->ldst_labels);
#endif
@@ -6286,13 +6599,88 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
@@ -6286,13 +6599,94 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
return -2;
}
@@ -2040,6 +2167,12 @@ index 6dc3072f92..214e66e9d6 100644
#endif
+#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
+ if (wasm_tci_only_tb) {
+ for (int i = 0; i < get_core_nums(); i++) {
+ export_vec_base[i] = WASM_TCI_ONLY_ENTRY;
+ }
+ }
+
+ tcg_sub_out8(s, 0x0b); //end if
+ tcg_sub_out8(s, 0x0b); //end loop
+ tcg_sub_out8(s, 0x0); // unreachable
@@ -2119,10 +2252,10 @@ index 6dc3072f92..214e66e9d6 100644
diff --git c/tcg/wasm32.c w/tcg/wasm32.c
new file mode 100644
index 0000000000..55ad790f17
index 0000000000..19b31ed4df
--- /dev/null
+++ w/tcg/wasm32.c
@@ -0,0 +1,1246 @@
@@ -0,0 +1,1275 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
@@ -2154,8 +2287,10 @@ index 0000000000..55ad790f17
+#include <emscripten.h>
+#include <emscripten/threading.h>
+#include "wasm32.h"
+#include "exec/translation-block.h"
+
+__thread uintptr_t tci_tb_ptr;
+__thread bool wasm_tci_only_tb;
+
+/* Disassemble TCI bytecode. */
+int print_insn_tci(bfd_vma addr, disassemble_info *info)
@@ -2191,12 +2326,16 @@ index 0000000000..55ad790f17
+ });
+ var ptr = export_vec_begin + 4 * Module.__wasm32_tb.cur_core_num;
+ const fidx = addFunction(inst.exports.start, 'ii');
+ Module.__wasm32_tb.dynamic_functions.add(fidx);
+ memory_v.setUint32(ptr, fidx, true);
+
+ const remove_n = memory_v.getInt32(Module.__wasm32_tb.to_remove_instance_idx_ptr, true);
+ if (remove_n > 500) {
+ for (var i = 0; i < remove_n * 4; i += 4) {
+ removeFunction(memory_v.getInt32(Module.__wasm32_tb.to_remove_instance_ptr + i, true));
+ const fidx = memory_v.getInt32(Module.__wasm32_tb.to_remove_instance_ptr + i, true);
+ if (Module.__wasm32_tb.dynamic_functions.delete(fidx)) {
+ removeFunction(fidx);
+ }
+ }
+ memory_v.setInt32(Module.__wasm32_tb.to_remove_instance_idx_ptr, 0, true);
+ }
@@ -2212,7 +2351,10 @@ index 0000000000..55ad790f17
+ const memory_v = new DataView(HEAP8.buffer);
+ const remove_n = memory_v.getInt32(tb.to_remove_instance_idx_ptr, true);
+ for (var i = 0; i < remove_n * 4; i += 4) {
+ removeFunction(memory_v.getInt32(tb.to_remove_instance_ptr + i, true));
+ const fidx = memory_v.getInt32(tb.to_remove_instance_ptr + i, true);
+ if (tb.dynamic_functions.delete(fidx)) {
+ removeFunction(fidx);
+ }
+ }
+ memory_v.setInt32(tb.to_remove_instance_idx_ptr, 0, true);
+});
@@ -2272,6 +2414,7 @@ index 0000000000..55ad790f17
+ cur_core_num: cur_core_num,
+ to_remove_instance_ptr: to_remove_instance_ptr,
+ to_remove_instance_idx_ptr: to_remove_instance_idx_ptr,
+ dynamic_functions: new Set(),
+ };
+});
+
@@ -2627,6 +2770,19 @@ index 0000000000..55ad790f17
+
+ uint64_t target_addr = tlb_load(env, taddr, mop, ptr, false);
+ if (target_addr != 0) {
+ uint64_t mem_bytes = (uint64_t)__builtin_wasm_memory_size(0) << 16;
+ if (target_addr + (1u << (mop & MO_SIZE)) > mem_bytes) {
+ TranslationBlock *tb = tcg_tb_lookup(ra);
+ fprintf(stderr,
+ "[sd-watch] OOB store pc=%08llx gaddr=%08llx haddr=%08llx size=%u value=%08llx membytes=%08llx\n",
+ (unsigned long long)(tb ? tb->pc : 0),
+ (unsigned long long)taddr, (unsigned long long)target_addr,
+ 1u << (mop & MO_SIZE), (unsigned long long)val,
+ (unsigned long long)mem_bytes);
+ return;
+ }
+ }
+ if (target_addr != 0) {
+ switch (mop & MO_SIZE) {
+ case MO_UB:
+ *(uint8_t*)target_addr = (uint8_t)val;
@@ -3252,7 +3408,9 @@ index 0000000000..55ad790f17
+ tb_ptr = *(uint32_t **)ptr;
+ ctx.tb_ptr = tb_ptr;
+ int tb_entry_ptr = (uint32_t)tb_ptr + export_vec_off;
+ if ((*(int32_t*)tb_entry_ptr <= 0) && (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM))) {
+ if (*(int32_t *)tb_entry_ptr == WASM_TCI_ONLY_ENTRY) {
+ /* ponytail: Store TBs use TCI while tracing SD object corruption. */
+ } else if ((*(int32_t*)tb_entry_ptr <= 0) && (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM))) {
+ *(int32_t*)tb_entry_ptr -= 1;
+ } else {
+ // enter to wasm TB
@@ -3273,7 +3431,9 @@ index 0000000000..55ad790f17
+
+ ctx.tb_ptr = tb_ptr;
+ int tb_entry_ptr = (uint32_t)tb_ptr + export_vec_off;
+ if ((*(int32_t*)tb_entry_ptr <= 0) && (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM))) {
+ if (*(int32_t *)tb_entry_ptr == WASM_TCI_ONLY_ENTRY) {
+ /* Continue in TCI. */
+ } else if ((*(int32_t*)tb_entry_ptr <= 0) && (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM))) {
+ *(int32_t*)tb_entry_ptr -= 1;
+ } else {
+ // enter to wasm TB
@@ -3355,6 +3515,8 @@ index 0000000000..55ad790f17
+ uint32_t res;
+ if (*(int32_t*)tb_entry_ptr > 0) {
+ res = ((wasm_func_ptr)(*(uint32_t*)tb_entry_ptr))(&ctx);
+ } else if (*(int32_t *)tb_entry_ptr == WASM_TCI_ONLY_ENTRY) {
+ res = tcg_qemu_tb_exec_tci(env);
+ } else if (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM)) {
+ *(int32_t*)tb_entry_ptr -= 1;
+ res = tcg_qemu_tb_exec_tci(env);
@@ -3371,10 +3533,10 @@ index 0000000000..55ad790f17
+#endif
diff --git c/tcg/wasm32.h w/tcg/wasm32.h
new file mode 100644
index 0000000000..1527bf4875
index 0000000000..a8b525abe3
--- /dev/null
+++ w/tcg/wasm32.h
@@ -0,0 +1,46 @@
@@ -0,0 +1,49 @@
+#ifndef TCG_WASM32_H
+#define TCG_WASM32_H
+
@@ -3418,7 +3580,10 @@ index 0000000000..1527bf4875
+
+void init_wasm32();
+
+extern __thread bool wasm_tci_only_tb;
+
+#define INSTANTIATE_NUM 1500
+#define WASM_TCI_ONLY_ENTRY (-2147483647 - 1)
+
+#endif
diff --git c/tcg/wasm32/tcg-target-con-set.h w/tcg/wasm32/tcg-target-con-set.h
@@ -3467,10 +3632,10 @@ index 0000000000..196395aef9
+#endif
diff --git c/tcg/wasm32/tcg-target.c.inc w/tcg/wasm32/tcg-target.c.inc
new file mode 100644
index 0000000000..9e82297a3f
index 0000000000..053c941f99
--- /dev/null
+++ w/tcg/wasm32/tcg-target.c.inc
@@ -0,0 +1,3824 @@
@@ -0,0 +1,3826 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
@@ -6843,6 +7008,7 @@ index 0000000000..9e82297a3f
+}
+static void tcg_out_qemu_st(TCGContext *s, TCGOpcode opc, const TCGArg *args, bool is_64)
+{
+ wasm_tci_only_tb = true;
+ tcg_tci_out_qemu_ldst(s, opc, args);
+ tcg_wasm_out_qemu_st(s, args, is_64);
+}
@@ -7246,6 +7412,7 @@ index 0000000000..9e82297a3f
+void tcg_out_init() {
+ current_label_pos = 0;
+ env_cached = false;
+ wasm_tci_only_tb = false;
+}
+
+/* Test if a constant matches the constraint. */