more
This commit is contained in:
@@ -224,6 +224,30 @@ index 49814ec4af..0715610d37 100644
|
||||
assert(tcg_enabled());
|
||||
g_assert(!icount_enabled());
|
||||
|
||||
diff --git c/accel/tcg/tcg-accel-ops-rr.c w/accel/tcg/tcg-accel-ops-rr.c
|
||||
index 8ebadf8e9e..1e38df86e8 100644
|
||||
--- c/accel/tcg/tcg-accel-ops-rr.c
|
||||
+++ w/accel/tcg/tcg-accel-ops-rr.c
|
||||
@@ -177,11 +177,19 @@ static int rr_cpu_count(void)
|
||||
* elsewhere.
|
||||
*/
|
||||
|
||||
+#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
|
||||
+#include "../../tcg/wasm32.h"
|
||||
+#endif
|
||||
+
|
||||
static void *rr_cpu_thread_fn(void *arg)
|
||||
{
|
||||
Notifier force_rcu;
|
||||
CPUState *cpu = arg;
|
||||
|
||||
+#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
|
||||
+ init_wasm32();
|
||||
+#endif
|
||||
+
|
||||
assert(tcg_enabled());
|
||||
rcu_register_thread();
|
||||
force_rcu.notify = rr_force_rcu;
|
||||
diff --git c/backends/meson.build w/backends/meson.build
|
||||
index da714b93d1..9b88d22685 100644
|
||||
--- c/backends/meson.build
|
||||
@@ -278,6 +302,223 @@ index 90fa54352c..0fa9cc31b6 100644
|
||||
|
||||
/*
|
||||
* parse_zone - Fill a zone descriptor
|
||||
diff --git c/block/vvfat.c w/block/vvfat.c
|
||||
index 8ffe8b3b9b..4cf02d9a55 100644
|
||||
--- c/block/vvfat.c
|
||||
+++ w/block/vvfat.c
|
||||
@@ -749,6 +749,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
||||
const char* dirname = mapping->path;
|
||||
int first_cluster = mapping->begin;
|
||||
int parent_index = mapping->info.dir.parent_mapping_index;
|
||||
+ bool is_root = parent_index < 0;
|
||||
mapping_t* parent_mapping = (mapping_t*)
|
||||
(parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
|
||||
int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
|
||||
@@ -765,9 +766,9 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
||||
}
|
||||
|
||||
i = mapping->info.dir.first_dir_index =
|
||||
- first_cluster == 0 ? 0 : s->directory.next;
|
||||
+ is_root ? 0 : s->directory.next;
|
||||
|
||||
- if (first_cluster != 0) {
|
||||
+ if (!is_root) {
|
||||
/* create the top entries of a subdirectory */
|
||||
(void)create_short_and_long_name(s, i, ".", 1);
|
||||
(void)create_short_and_long_name(s, i, "..", 1);
|
||||
@@ -781,13 +782,14 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
||||
int is_dot=!strcmp(entry->d_name,".");
|
||||
int is_dotdot=!strcmp(entry->d_name,"..");
|
||||
|
||||
- if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
|
||||
+ if (is_root && s->fat_type != 32 &&
|
||||
+ s->directory.next >= s->root_entries - 1) {
|
||||
fprintf(stderr, "Too many entries in root directory\n");
|
||||
closedir(dir);
|
||||
return -2;
|
||||
}
|
||||
|
||||
- if(first_cluster == 0 && (is_dotdot || is_dot))
|
||||
+ if(is_root && (is_dotdot || is_dot))
|
||||
continue;
|
||||
|
||||
buffer = g_malloc(length);
|
||||
@@ -860,8 +862,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
||||
memset(direntry,0,sizeof(direntry_t));
|
||||
}
|
||||
|
||||
- if (s->fat_type != 32 &&
|
||||
- mapping_index == 0 &&
|
||||
+ if (s->fat_type != 32 && is_root &&
|
||||
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)
|
||||
* 0x20 / s->cluster_size;
|
||||
mapping->end = first_cluster;
|
||||
|
||||
- direntry = array_get(&(s->directory), mapping->dir_index);
|
||||
- set_begin_of_direntry(direntry, mapping->begin);
|
||||
+ if (!is_root) {
|
||||
+ direntry = array_get(&(s->directory), mapping->dir_index);
|
||||
+ set_begin_of_direntry(direntry, mapping->begin);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
+ + (s->fat_type == 32 ? 2 : 0);
|
||||
}
|
||||
|
||||
static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
|
||||
{
|
||||
- return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
|
||||
+ return s->offset_to_root_dir + s->sectors_per_cluster
|
||||
+ * (cluster_num - (s->fat_type == 32 ? 2 : 0));
|
||||
}
|
||||
|
||||
static int init_directories(BDRVVVFATState* s,
|
||||
@@ -934,11 +939,12 @@ static int init_directories(BDRVVVFATState* s,
|
||||
init_fat(s);
|
||||
|
||||
/* TODO: if there are more entries, bootsector has to be adjusted! */
|
||||
- s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
|
||||
+ s->root_entries = s->fat_type == 32 ? 0 :
|
||||
+ 0x02 * 0x10 * s->sectors_per_cluster;
|
||||
s->cluster_count=sector2cluster(s, s->sector_count);
|
||||
|
||||
mapping = array_get_next(&(s->mapping));
|
||||
- mapping->begin = 0;
|
||||
+ mapping->begin = s->fat_type == 32 ? 2 : 0;
|
||||
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,
|
||||
mapping->read_only = 0;
|
||||
s->path = mapping->path;
|
||||
|
||||
- for (i = 0, cluster = 0; i < s->mapping.next; i++) {
|
||||
- /* MS-DOS expects the FAT to be 0 for the root directory
|
||||
- * (except for the media byte). */
|
||||
- /* LATER TODO: still true for FAT32? */
|
||||
- int fix_fat = (i != 0);
|
||||
+ for (i = 0, cluster = s->fat_type == 32 ? 2 : 0;
|
||||
+ i < s->mapping.next; i++) {
|
||||
+ /* FAT12/16 stores the root directory outside the cluster chain. */
|
||||
+ int fix_fat = (i != 0 || s->fat_type == 32);
|
||||
mapping = array_get(&(s->mapping), i);
|
||||
|
||||
if (mapping->mode & MODE_DIRECTORY) {
|
||||
@@ -1026,22 +1031,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;
|
||||
- bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
|
||||
+ bootsector->sectors_per_fat = s->fat_type == 32 ? 0 :
|
||||
+ cpu_to_le16(s->sectors_per_fat);
|
||||
bootsector->sectors_per_track = cpu_to_le16(secs);
|
||||
bootsector->number_of_heads = cpu_to_le16(heads);
|
||||
bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
|
||||
bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
|
||||
|
||||
- /* LATER TODO: if FAT32, this is wrong */
|
||||
- /* drive_number: fda=0, hda=0x80 */
|
||||
- bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
|
||||
- bootsector->u.fat16.signature=0x29;
|
||||
- bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
|
||||
-
|
||||
- memcpy(bootsector->u.fat16.volume_label, s->volume_label,
|
||||
- sizeof(bootsector->u.fat16.volume_label));
|
||||
- memcpy(bootsector->u.fat16.fat_type,
|
||||
- s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8);
|
||||
+ if (s->fat_type == 32) {
|
||||
+ bootsector->u.fat32.sectors_per_fat = cpu_to_le32(s->sectors_per_fat);
|
||||
+ bootsector->u.fat32.first_cluster_of_root_dir = cpu_to_le32(2);
|
||||
+ bootsector->u.fat32.info_sector = cpu_to_le16(0xffff);
|
||||
+ bootsector->u.fat32.backup_boot_sector = cpu_to_le16(0xffff);
|
||||
+ bootsector->u.fat32.drive_number = 0x80;
|
||||
+ bootsector->u.fat32.signature = 0x29;
|
||||
+ bootsector->u.fat32.id = cpu_to_le32(0xfabe1afd);
|
||||
+ memcpy(bootsector->u.fat32.volume_label, s->volume_label,
|
||||
+ sizeof(bootsector->u.fat32.volume_label));
|
||||
+ memcpy(bootsector->u.fat32.fat_type, "FAT32 ", 8);
|
||||
+ } else {
|
||||
+ /* drive_number: fda=0, hda=0x80 */
|
||||
+ bootsector->u.fat16.drive_number =
|
||||
+ s->offset_to_bootsector == 0 ? 0 : 0x80;
|
||||
+ bootsector->u.fat16.signature=0x29;
|
||||
+ bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
|
||||
+ memcpy(bootsector->u.fat16.volume_label, s->volume_label,
|
||||
+ sizeof(bootsector->u.fat16.volume_label));
|
||||
+ memcpy(bootsector->u.fat16.fat_type,
|
||||
+ s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8);
|
||||
+ }
|
||||
bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
|
||||
|
||||
return 0;
|
||||
@@ -1139,6 +1157,7 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
{
|
||||
BDRVVVFATState *s = bs->opaque;
|
||||
int cyls, heads, secs;
|
||||
+ uint64_t total_sectors;
|
||||
bool floppy;
|
||||
const char *dirname, *label;
|
||||
QemuOpts *opts;
|
||||
@@ -1205,7 +1224,9 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
||||
switch (s->fat_type) {
|
||||
case 32:
|
||||
+#ifndef EMSCRIPTEN
|
||||
warn_report("FAT32 has not been tested. You are welcome to do so!");
|
||||
+#endif
|
||||
break;
|
||||
case 16:
|
||||
case 12:
|
||||
@@ -1219,8 +1240,17 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
||||
s->bs = bs;
|
||||
|
||||
- /* LATER TODO: if FAT32, adjust */
|
||||
- s->sectors_per_cluster=0x10;
|
||||
+#ifdef EMSCRIPTEN
|
||||
+ if (!floppy && s->fat_type == 32) {
|
||||
+ /* Browser SD Geometry - A larger cluster keeps the synthesized 32 GiB FAT near 4 MiB. */
|
||||
+ s->sectors_per_cluster = 0x40;
|
||||
+ total_sectors = 32ULL * 1024 * 1024 * 1024 / BDRV_SECTOR_SIZE;
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
+ s->sectors_per_cluster = 0x10;
|
||||
+ total_sectors = (uint64_t)cyls * heads * secs;
|
||||
+ }
|
||||
|
||||
s->current_cluster=0xffffffff;
|
||||
|
||||
@@ -1232,8 +1262,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));
|
||||
|
||||
- s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
|
||||
- bs->total_sectors = cyls * heads * secs;
|
||||
+ s->sector_count = total_sectors - s->offset_to_bootsector;
|
||||
+ bs->total_sectors = total_sectors;
|
||||
|
||||
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
|
||||
} 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;
|
||||
+ 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) {
|
||||
/* LATER TODO: strict: return -1; */
|
||||
memset(buf+i*0x200,0,0x200);
|
||||
diff --git c/configs/devices/riscv32-softmmu/xteink.mak w/configs/devices/riscv32-softmmu/xteink.mak
|
||||
new file mode 100644
|
||||
index 0000000000..a9179b4119
|
||||
@@ -613,6 +854,39 @@ index 1879b5c2df..e3f09cc51b 100644
|
||||
}
|
||||
|
||||
static void esp32c3_cache_init(Object *obj)
|
||||
diff --git c/hw/misc/esp32c3_jtag.c w/hw/misc/esp32c3_jtag.c
|
||||
index 82ee69717b..64a971f183 100644
|
||||
--- c/hw/misc/esp32c3_jtag.c
|
||||
+++ w/hw/misc/esp32c3_jtag.c
|
||||
@@ -16,10 +16,18 @@
|
||||
#include "hw/misc/esp32c3_jtag.h"
|
||||
|
||||
|
||||
+/* USB Serial JTAG Console Tap - The firmware routes ESP-IDF console output (incl. panic dumps) through this peripheral. EP1 is the byte FIFO; EP1_CONF bit1 (SERIAL_IN_EP_DATA_FREE) must read set so the driver believes the TX FIFO can always accept a byte. */
|
||||
+#define ESP32C3_JTAG_EP1_REG 0x00
|
||||
+#define ESP32C3_JTAG_EP1_CONF_REG 0x04
|
||||
+#define ESP32C3_JTAG_IN_EP_DATA_FREE (1u << 1)
|
||||
+
|
||||
static uint64_t esp32c3_jtag_read(void *opaque, hwaddr addr, unsigned int size)
|
||||
{
|
||||
ESP32C3UsbJtagState *s = ESP32C3_JTAG(opaque);
|
||||
(void) s;
|
||||
+ if (addr == ESP32C3_JTAG_EP1_CONF_REG) {
|
||||
+ return ESP32C3_JTAG_IN_EP_DATA_FREE;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,6 +35,9 @@ static void esp32c3_jtag_write(void *opaque, hwaddr addr, uint64_t value, unsign
|
||||
{
|
||||
ESP32C3UsbJtagState *s = ESP32C3_JTAG(opaque);
|
||||
(void) s;
|
||||
+ if (addr == ESP32C3_JTAG_EP1_REG) {
|
||||
+ fputc((int)(value & 0xff), stderr);
|
||||
+ }
|
||||
}
|
||||
|
||||
static const MemoryRegionOps esp32c3_jtag_ops = {
|
||||
diff --git c/hw/misc/esp_sha.c w/hw/misc/esp_sha.c
|
||||
index c9fa2e610a..cc186595eb 100644
|
||||
--- c/hw/misc/esp_sha.c
|
||||
@@ -707,7 +981,7 @@ index c9fa2e610a..cc186595eb 100644
|
||||
},
|
||||
};
|
||||
diff --git c/hw/riscv/esp32c3.c w/hw/riscv/esp32c3.c
|
||||
index 2f1ccbfbb0..febc96bfe3 100644
|
||||
index 2f1ccbfbb0..af8bb86c97 100644
|
||||
--- c/hw/riscv/esp32c3.c
|
||||
+++ w/hw/riscv/esp32c3.c
|
||||
@@ -57,6 +57,10 @@
|
||||
@@ -721,7 +995,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
#define ESP32C3_IO_WARNING 0
|
||||
|
||||
#define ESP32C3_RESET_ADDRESS 0x40000000
|
||||
@@ -103,6 +107,27 @@ struct Esp32C3MachineState {
|
||||
@@ -103,6 +107,29 @@ struct Esp32C3MachineState {
|
||||
Esp32C3TWAIState twai;
|
||||
};
|
||||
|
||||
@@ -732,6 +1006,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
+{
|
||||
+ if (xteink_wasm_machine && channel >= 0 &&
|
||||
+ channel < ESP32C3_ADC_CHANNELS) {
|
||||
+ fprintf(stderr, "[button] adc channel=%d value=%u\n", channel, value);
|
||||
+ qatomic_set(&xteink_wasm_machine->adc.input[channel],
|
||||
+ MIN(value, UINT32_C(0xfff)));
|
||||
+ }
|
||||
@@ -740,6 +1015,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
+EMSCRIPTEN_KEEPALIVE void xteink_wasm_set_gpio(int pin, int level)
|
||||
+{
|
||||
+ if (xteink_wasm_machine && pin >= 0 && pin < ESP32_GPIO_COUNT) {
|
||||
+ fprintf(stderr, "[button] gpio pin=%d level=%d\n", pin, level);
|
||||
+ esp32_gpio_set_input_level(&xteink_wasm_machine->gpio.parent,
|
||||
+ pin, level);
|
||||
+ }
|
||||
@@ -749,7 +1025,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
/* Fake register used by ESP-IDF application to determine whether the code is running on real hardware or on QEMU */
|
||||
#define A_SYSCON_ORIGIN_REG 0x3F8
|
||||
/* Temporary macro for generating a random value from register SYSCON_RND_DATA_REG */
|
||||
@@ -421,12 +446,18 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -421,12 +448,18 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
object_initialize_child(OBJECT(machine), "efuse", &ms->efuse, TYPE_ESP32C3_EFUSE);
|
||||
object_initialize_child(OBJECT(machine), "clock", &ms->clock, TYPE_ESP32C3_CLOCK);
|
||||
object_initialize_child(OBJECT(machine), "sha", &ms->sha, TYPE_ESP32C3_SHA);
|
||||
@@ -768,7 +1044,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
object_initialize_child(OBJECT(machine), "timg0", &ms->timg[0], TYPE_ESP32C3_TIMG);
|
||||
object_initialize_child(OBJECT(machine), "timg1", &ms->timg[1], TYPE_ESP32C3_TIMG);
|
||||
object_initialize_child(OBJECT(machine), "systimer", &ms->systimer, TYPE_ESP32C3_SYSTIMER);
|
||||
@@ -484,7 +515,9 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -484,7 +517,9 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
|
||||
/* SPI1 controller (SPI Flash) */
|
||||
{
|
||||
@@ -778,7 +1054,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
sysbus_realize(SYS_BUS_DEVICE(&ms->spi1), &error_fatal);
|
||||
MemoryRegion *mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&ms->spi1), 0);
|
||||
memory_region_add_subregion_overlap(sys_mem, DR_REG_SPI1_BASE, mr, 0);
|
||||
@@ -539,7 +572,9 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -539,7 +574,9 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
if (blk) {
|
||||
ms->cache.flash_blk = blk;
|
||||
}
|
||||
@@ -788,7 +1064,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
sysbus_realize(SYS_BUS_DEVICE(&ms->cache), &error_fatal);
|
||||
MemoryRegion *mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&ms->cache), 0);
|
||||
memory_region_add_subregion_overlap(sys_mem, DR_REG_EXTMEM_BASE, mr, 0);
|
||||
@@ -635,6 +670,7 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -635,6 +672,7 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
qdev_get_gpio_in(intmatrix_dev, ETS_SHA_INTR_SOURCE));
|
||||
}
|
||||
|
||||
@@ -796,7 +1072,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
/* AES realization */
|
||||
{
|
||||
ms->aes.parent.gdma = ESP_GDMA(&ms->gdma);
|
||||
@@ -654,6 +690,8 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -654,6 +692,8 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
qdev_get_gpio_in(intmatrix_dev, ETS_RSA_INTR_SOURCE));
|
||||
}
|
||||
|
||||
@@ -805,7 +1081,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
/* HMAC realization */
|
||||
{
|
||||
ms->hmac.parent.efuse = ESP_EFUSE(&ms->efuse);
|
||||
@@ -662,6 +700,7 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -662,6 +702,7 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
memory_region_add_subregion_overlap(sys_mem, DR_REG_HMAC_BASE, mr, 0);
|
||||
}
|
||||
|
||||
@@ -813,7 +1089,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
/* Digital Signature realization */
|
||||
{
|
||||
ms->ds.parent.hmac = ESP_HMAC(&ms->hmac);
|
||||
@@ -682,6 +721,8 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
@@ -682,6 +723,8 @@ static void esp32c3_machine_init(MachineState *machine)
|
||||
memory_region_add_subregion_overlap(sys_mem, DR_REG_AES_XTS_BASE, mr, 0);
|
||||
}
|
||||
|
||||
@@ -822,7 +1098,7 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
/* RGB display realization */
|
||||
if (!ms->xteink) {
|
||||
/* Give the internal RAM memory region to the display */
|
||||
@@ -706,6 +747,9 @@ static void xteink_machine_init(MachineState *machine)
|
||||
@@ -706,6 +749,9 @@ static void xteink_machine_init(MachineState *machine)
|
||||
Esp32C3MachineState *ms = ESP32C3_MACHINE(machine);
|
||||
ms->xteink = true;
|
||||
esp32c3_machine_init(machine);
|
||||
@@ -832,6 +1108,33 @@ index 2f1ccbfbb0..febc96bfe3 100644
|
||||
|
||||
/* X3 exposes the fingerprint chips; X4 omits them so stock firmware's
|
||||
* all-NAK probe selects X4. The X4 panel is a blank protocol stub. */
|
||||
diff --git c/hw/riscv/esp32c3_intmatrix.c w/hw/riscv/esp32c3_intmatrix.c
|
||||
index c1376b7299..1275808dc0 100644
|
||||
--- c/hw/riscv/esp32c3_intmatrix.c
|
||||
+++ w/hw/riscv/esp32c3_intmatrix.c
|
||||
@@ -25,9 +25,10 @@
|
||||
#define INTMATRIX_DEBUG 0
|
||||
#define INTMATRIX_WARNING 0
|
||||
|
||||
-#define BIT_SET(reg, bit) ((reg) & BIT(bit))
|
||||
-#define CLEAR_BIT(reg, bit) do { (reg) &= ~BIT(bit); } while(0)
|
||||
-#define SET_BIT(reg, bit) do { (reg) |= BIT(bit); } while(0)
|
||||
+/* 64-bit Shifts For irq_levels - There are up to 62 interrupt sources, so bit ops on the uint64_t level mask must shift in 64-bit. QEMU's BIT() is `1UL << nr`, which is only 32-bit on wasm32 and silently aliases source N to N-32. */
|
||||
+#define BIT_SET(reg, bit) ((reg) & (1ULL << (bit)))
|
||||
+#define CLEAR_BIT(reg, bit) do { (reg) &= ~(1ULL << (bit)); } while(0)
|
||||
+#define SET_BIT(reg, bit) do { (reg) |= (1ULL << (bit)); } while(0)
|
||||
|
||||
|
||||
static int esp32c3_get_output_line_level(ESP32C3IntMatrixState *s, int line)
|
||||
@@ -36,7 +37,7 @@ static int esp32c3_get_output_line_level(ESP32C3IntMatrixState *s, int line)
|
||||
|
||||
for (int i = 0; level_shared == 0 && i < ESP32C3_INT_MATRIX_INPUTS; i++) {
|
||||
const uint_fast8_t mapped = s->irq_map[i];
|
||||
- if (mapped == line && (s->irq_levels & BIT(i)))
|
||||
+ if (mapped == line && (s->irq_levels & (1ULL << i)))
|
||||
{
|
||||
level_shared |= 1;
|
||||
}
|
||||
diff --git c/include/exec/exec-all.h w/include/exec/exec-all.h
|
||||
index 2e4c4cc4b4..99e6da08c9 100644
|
||||
--- c/include/exec/exec-all.h
|
||||
|
||||
Reference in New Issue
Block a user