pull-loongarch-20221104
v2: - fix win32 build error; - Add Rui Wang' patches. -----BEGIN PGP SIGNATURE----- iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCY2TZsAAKCRBAov/yOSY+ 30kyA/9VEYvFQaXM9RP78OoiK0bANiByTCQMXCAuos1wXui/FwAcqE9YWXZStzH0 MHdT2PyH680w9aKjhHuPbGs5xU911cQ94SPWzcTtM4HfEH+3N7RBfF0gS7MA+DLa 92vLqEIDC6SbAlY4/CRJVJmOl58d4uhEUUpq6eVzmJHcA3W5qw== =wblG -----END PGP SIGNATURE----- Merge tag 'pull-loongarch-20221104' of https://gitlab.com/gaosong/qemu into staging pull-loongarch-20221104 v2: - fix win32 build error; - Add Rui Wang' patches. # -----BEGIN PGP SIGNATURE----- # # iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCY2TZsAAKCRBAov/yOSY+ # 30kyA/9VEYvFQaXM9RP78OoiK0bANiByTCQMXCAuos1wXui/FwAcqE9YWXZStzH0 # MHdT2PyH680w9aKjhHuPbGs5xU911cQ94SPWzcTtM4HfEH+3N7RBfF0gS7MA+DLa # 92vLqEIDC6SbAlY4/CRJVJmOl58d4uhEUUpq6eVzmJHcA3W5qw== # =wblG # -----END PGP SIGNATURE----- # gpg: Signature made Fri 04 Nov 2022 05:21:52 EDT # gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF # gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF * tag 'pull-loongarch-20221104' of https://gitlab.com/gaosong/qemu: target/loongarch: Fix emulation of float-point disable exception target/loongarch: Adjust the layout of hardware flags bit fields target/loongarch: Fix raise_mmu_exception() set wrong exception_index target/loongarch: Add exception subcode hw/loongarch: Add TPM device for LoongArch virt machine hw/loongarch: Improve fdt for LoongArch virt machine hw/loongarch: Load FDT table into dram memory space hw/intc: Fix LoongArch extioi coreisr accessing hw/intc: Convert the memops to with_attrs in LoongArch extioi Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
7a033008cc
@ -68,44 +68,46 @@ static void extioi_setirq(void *opaque, int irq, int level)
|
|||||||
extioi_update_irq(s, irq, level);
|
extioi_update_irq(s, irq, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size)
|
static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data,
|
||||||
|
unsigned size, MemTxAttrs attrs)
|
||||||
{
|
{
|
||||||
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
||||||
unsigned long offset = addr & 0xffff;
|
unsigned long offset = addr & 0xffff;
|
||||||
uint32_t index, cpu, ret = 0;
|
uint32_t index, cpu;
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
|
case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
|
||||||
index = (offset - EXTIOI_NODETYPE_START) >> 2;
|
index = (offset - EXTIOI_NODETYPE_START) >> 2;
|
||||||
ret = s->nodetype[index];
|
*data = s->nodetype[index];
|
||||||
break;
|
break;
|
||||||
case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
|
case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
|
||||||
index = (offset - EXTIOI_IPMAP_START) >> 2;
|
index = (offset - EXTIOI_IPMAP_START) >> 2;
|
||||||
ret = s->ipmap[index];
|
*data = s->ipmap[index];
|
||||||
break;
|
break;
|
||||||
case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
|
case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
|
||||||
index = (offset - EXTIOI_ENABLE_START) >> 2;
|
index = (offset - EXTIOI_ENABLE_START) >> 2;
|
||||||
ret = s->enable[index];
|
*data = s->enable[index];
|
||||||
break;
|
break;
|
||||||
case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
|
case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
|
||||||
index = (offset - EXTIOI_BOUNCE_START) >> 2;
|
index = (offset - EXTIOI_BOUNCE_START) >> 2;
|
||||||
ret = s->bounce[index];
|
*data = s->bounce[index];
|
||||||
break;
|
break;
|
||||||
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
|
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
|
||||||
index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
|
index = (offset - EXTIOI_COREISR_START) >> 2;
|
||||||
cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
|
/* using attrs to get current cpu index */
|
||||||
ret = s->coreisr[cpu][index];
|
cpu = attrs.requester_id;
|
||||||
|
*data = s->coreisr[cpu][index];
|
||||||
break;
|
break;
|
||||||
case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
|
case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
|
||||||
index = (offset - EXTIOI_COREMAP_START) >> 2;
|
index = (offset - EXTIOI_COREMAP_START) >> 2;
|
||||||
ret = s->coremap[index];
|
*data = s->coremap[index];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_loongarch_extioi_readw(addr, ret);
|
trace_loongarch_extioi_readw(addr, *data);
|
||||||
return ret;
|
return MEMTX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
|
static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
|
||||||
@ -127,8 +129,9 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extioi_writew(void *opaque, hwaddr addr,
|
static MemTxResult extioi_writew(void *opaque, hwaddr addr,
|
||||||
uint64_t val, unsigned size)
|
uint64_t val, unsigned size,
|
||||||
|
MemTxAttrs attrs)
|
||||||
{
|
{
|
||||||
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
||||||
int i, cpu, index, old_data, irq;
|
int i, cpu, index, old_data, irq;
|
||||||
@ -183,8 +186,9 @@ static void extioi_writew(void *opaque, hwaddr addr,
|
|||||||
s->bounce[index] = val;
|
s->bounce[index] = val;
|
||||||
break;
|
break;
|
||||||
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
|
case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
|
||||||
index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
|
index = (offset - EXTIOI_COREISR_START) >> 2;
|
||||||
cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
|
/* using attrs to get current cpu index */
|
||||||
|
cpu = attrs.requester_id;
|
||||||
old_data = s->coreisr[cpu][index];
|
old_data = s->coreisr[cpu][index];
|
||||||
s->coreisr[cpu][index] = old_data & ~val;
|
s->coreisr[cpu][index] = old_data & ~val;
|
||||||
/* write 1 to clear interrrupt */
|
/* write 1 to clear interrrupt */
|
||||||
@ -231,11 +235,12 @@ static void extioi_writew(void *opaque, hwaddr addr,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return MEMTX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps extioi_ops = {
|
static const MemoryRegionOps extioi_ops = {
|
||||||
.read = extioi_readw,
|
.read_with_attrs = extioi_readw,
|
||||||
.write = extioi_writew,
|
.write_with_attrs = extioi_writew,
|
||||||
.impl.min_access_size = 4,
|
.impl.min_access_size = 4,
|
||||||
.impl.max_access_size = 4,
|
.impl.max_access_size = 4,
|
||||||
.valid.min_access_size = 4,
|
.valid.min_access_size = 4,
|
||||||
|
@ -306,6 +306,5 @@ loongarch_msi_set_irq(int irq_num) "set msi irq %d"
|
|||||||
|
|
||||||
# loongarch_extioi.c
|
# loongarch_extioi.c
|
||||||
loongarch_extioi_setirq(int irq, int level) "set extirq irq %d level %d"
|
loongarch_extioi_setirq(int irq, int level) "set extirq irq %d level %d"
|
||||||
loongarch_extioi_readw(uint64_t addr, uint32_t val) "addr: 0x%"PRIx64 "val: 0x%x"
|
loongarch_extioi_readw(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64
|
||||||
loongarch_extioi_writew(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64
|
loongarch_extioi_writew(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
|
|
||||||
#include "hw/acpi/generic_event_device.h"
|
#include "hw/acpi/generic_event_device.h"
|
||||||
#include "hw/pci-host/gpex.h"
|
#include "hw/pci-host/gpex.h"
|
||||||
|
#include "sysemu/tpm.h"
|
||||||
|
#include "hw/platform-bus.h"
|
||||||
|
#include "hw/acpi/aml-build.h"
|
||||||
|
|
||||||
#define ACPI_BUILD_ALIGN_SIZE 0x1000
|
#define ACPI_BUILD_ALIGN_SIZE 0x1000
|
||||||
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
||||||
@ -275,6 +278,41 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
|
|||||||
acpi_dsdt_add_gpex(scope, &cfg);
|
acpi_dsdt_add_gpex(scope, &cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_TPM
|
||||||
|
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
|
||||||
|
{
|
||||||
|
PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
|
||||||
|
hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
|
||||||
|
SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
|
||||||
|
MemoryRegion *sbdev_mr;
|
||||||
|
hwaddr tpm_base;
|
||||||
|
|
||||||
|
if (!sbdev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||||
|
assert(tpm_base != -1);
|
||||||
|
|
||||||
|
tpm_base += pbus_base;
|
||||||
|
|
||||||
|
sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
|
||||||
|
|
||||||
|
Aml *dev = aml_device("TPM0");
|
||||||
|
aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
|
||||||
|
aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
|
||||||
|
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
|
||||||
|
|
||||||
|
Aml *crs = aml_resource_template();
|
||||||
|
aml_append(crs,
|
||||||
|
aml_memory32_fixed(tpm_base,
|
||||||
|
(uint32_t)memory_region_size(sbdev_mr),
|
||||||
|
AML_READ_WRITE));
|
||||||
|
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||||
|
aml_append(scope, dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* build DSDT */
|
/* build DSDT */
|
||||||
static void
|
static void
|
||||||
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||||
@ -289,7 +327,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|||||||
build_uart_device_aml(dsdt);
|
build_uart_device_aml(dsdt);
|
||||||
build_pci_device_aml(dsdt, lams);
|
build_pci_device_aml(dsdt, lams);
|
||||||
build_la_ged_aml(dsdt, machine);
|
build_la_ged_aml(dsdt, machine);
|
||||||
|
#ifdef CONFIG_TPM
|
||||||
|
acpi_dsdt_add_tpm(dsdt, lams);
|
||||||
|
#endif
|
||||||
/* System State Package */
|
/* System State Package */
|
||||||
scope = aml_scope("\\");
|
scope = aml_scope("\\");
|
||||||
pkg = aml_package(4);
|
pkg = aml_package(4);
|
||||||
@ -359,6 +399,15 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
|||||||
lams->oem_table_id);
|
lams->oem_table_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_TPM
|
||||||
|
/* TPM info */
|
||||||
|
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
|
||||||
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
|
build_tpm2(tables_blob, tables->linker,
|
||||||
|
tables->tcpalog, lams->oem_id,
|
||||||
|
lams->oem_table_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Add tables supplied by user (if any) */
|
/* Add tables supplied by user (if any) */
|
||||||
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
|
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
|
||||||
unsigned len = acpi_table_len(u);
|
unsigned len = acpi_table_len(u);
|
||||||
|
@ -41,6 +41,36 @@
|
|||||||
#include "hw/platform-bus.h"
|
#include "hw/platform-bus.h"
|
||||||
#include "hw/display/ramfb.h"
|
#include "hw/display/ramfb.h"
|
||||||
#include "hw/mem/pc-dimm.h"
|
#include "hw/mem/pc-dimm.h"
|
||||||
|
#include "sysemu/tpm.h"
|
||||||
|
|
||||||
|
static void fdt_add_rtc_node(LoongArchMachineState *lams)
|
||||||
|
{
|
||||||
|
char *nodename;
|
||||||
|
hwaddr base = VIRT_RTC_REG_BASE;
|
||||||
|
hwaddr size = VIRT_RTC_LEN;
|
||||||
|
MachineState *ms = MACHINE(lams);
|
||||||
|
|
||||||
|
nodename = g_strdup_printf("/rtc@%" PRIx64, base);
|
||||||
|
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||||
|
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc");
|
||||||
|
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 0x0, base, size);
|
||||||
|
g_free(nodename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fdt_add_uart_node(LoongArchMachineState *lams)
|
||||||
|
{
|
||||||
|
char *nodename;
|
||||||
|
hwaddr base = VIRT_UART_BASE;
|
||||||
|
hwaddr size = VIRT_UART_SIZE;
|
||||||
|
MachineState *ms = MACHINE(lams);
|
||||||
|
|
||||||
|
nodename = g_strdup_printf("/serial@%" PRIx64, base);
|
||||||
|
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||||
|
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
|
||||||
|
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
|
||||||
|
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
|
||||||
|
g_free(nodename);
|
||||||
|
}
|
||||||
|
|
||||||
static void create_fdt(LoongArchMachineState *lams)
|
static void create_fdt(LoongArchMachineState *lams)
|
||||||
{
|
{
|
||||||
@ -159,7 +189,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams)
|
|||||||
1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
|
1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
|
||||||
2, base_mmio, 2, size_mmio);
|
2, base_mmio, 2, size_mmio);
|
||||||
g_free(nodename);
|
g_free(nodename);
|
||||||
qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fdt_add_irqchip_node(LoongArchMachineState *lams)
|
static void fdt_add_irqchip_node(LoongArchMachineState *lams)
|
||||||
@ -423,6 +452,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
|
|||||||
qdev_get_gpio_in(pch_pic,
|
qdev_get_gpio_in(pch_pic,
|
||||||
VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
|
VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
|
||||||
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||||
|
fdt_add_uart_node(lams);
|
||||||
|
|
||||||
/* Network init */
|
/* Network init */
|
||||||
for (i = 0; i < nb_nics; i++) {
|
for (i = 0; i < nb_nics; i++) {
|
||||||
@ -443,6 +473,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
|
|||||||
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
|
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
|
||||||
qdev_get_gpio_in(pch_pic,
|
qdev_get_gpio_in(pch_pic,
|
||||||
VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
|
VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
|
||||||
|
fdt_add_rtc_node(lams);
|
||||||
|
|
||||||
pm_mem = g_new(MemoryRegion, 1);
|
pm_mem = g_new(MemoryRegion, 1);
|
||||||
memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
|
memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
|
||||||
@ -656,6 +687,7 @@ static void loongarch_init(MachineState *machine)
|
|||||||
MemoryRegion *address_space_mem = get_system_memory();
|
MemoryRegion *address_space_mem = get_system_memory();
|
||||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||||
int i;
|
int i;
|
||||||
|
hwaddr fdt_base;
|
||||||
|
|
||||||
if (!cpu_model) {
|
if (!cpu_model) {
|
||||||
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||||
@ -760,12 +792,16 @@ static void loongarch_init(MachineState *machine)
|
|||||||
lams->machine_done.notify = virt_machine_done;
|
lams->machine_done.notify = virt_machine_done;
|
||||||
qemu_add_machine_init_done_notifier(&lams->machine_done);
|
qemu_add_machine_init_done_notifier(&lams->machine_done);
|
||||||
fdt_add_pcie_node(lams);
|
fdt_add_pcie_node(lams);
|
||||||
|
/*
|
||||||
/* load fdt */
|
* Since lowmem region starts from 0, FDT base address is located
|
||||||
MemoryRegion *fdt_rom = g_new(MemoryRegion, 1);
|
* at 2 MiB to avoid NULL pointer access.
|
||||||
memory_region_init_rom(fdt_rom, NULL, "fdt", VIRT_FDT_SIZE, &error_fatal);
|
*
|
||||||
memory_region_add_subregion(get_system_memory(), VIRT_FDT_BASE, fdt_rom);
|
* Put the FDT into the memory map as a ROM image: this will ensure
|
||||||
rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, VIRT_FDT_BASE);
|
* the FDT is copied again upon reset, even if addr points into RAM.
|
||||||
|
*/
|
||||||
|
fdt_base = 2 * MiB;
|
||||||
|
qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
|
||||||
|
rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
|
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
|
||||||
@ -925,6 +961,9 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
|
|||||||
object_class_property_set_description(oc, "acpi",
|
object_class_property_set_description(oc, "acpi",
|
||||||
"Enable ACPI");
|
"Enable ACPI");
|
||||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||||
|
#ifdef CONFIG_TPM
|
||||||
|
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo loongarch_machine_types[] = {
|
static const TypeInfo loongarch_machine_types[] = {
|
||||||
|
@ -28,9 +28,6 @@
|
|||||||
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
|
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
|
||||||
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
|
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
|
||||||
|
|
||||||
#define VIRT_FDT_BASE 0x1c400000
|
|
||||||
#define VIRT_FDT_SIZE 0x100000
|
|
||||||
|
|
||||||
struct LoongArchMachineState {
|
struct LoongArchMachineState {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
MachineState parent_obj;
|
MachineState parent_obj;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#define VIRT_PCI_IRQS 48
|
#define VIRT_PCI_IRQS 48
|
||||||
#define VIRT_UART_IRQ (PCH_PIC_IRQ_OFFSET + 2)
|
#define VIRT_UART_IRQ (PCH_PIC_IRQ_OFFSET + 2)
|
||||||
#define VIRT_UART_BASE 0x1fe001e0
|
#define VIRT_UART_BASE 0x1fe001e0
|
||||||
|
#define VIRT_UART_SIZE 0X100
|
||||||
#define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3)
|
#define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3)
|
||||||
#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
|
#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
|
||||||
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
|
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
|
||||||
|
@ -48,6 +48,7 @@ static const char * const excp_names[] = {
|
|||||||
[EXCCODE_BRK] = "Break",
|
[EXCCODE_BRK] = "Break",
|
||||||
[EXCCODE_INE] = "Instruction Non-Existent",
|
[EXCCODE_INE] = "Instruction Non-Existent",
|
||||||
[EXCCODE_IPE] = "Instruction privilege error",
|
[EXCCODE_IPE] = "Instruction privilege error",
|
||||||
|
[EXCCODE_FPD] = "Floating Point Disabled",
|
||||||
[EXCCODE_FPE] = "Floating Point Exception",
|
[EXCCODE_FPE] = "Floating Point Exception",
|
||||||
[EXCCODE_DBP] = "Debug breakpoint",
|
[EXCCODE_DBP] = "Debug breakpoint",
|
||||||
[EXCCODE_BCE] = "Bound Check Exception",
|
[EXCCODE_BCE] = "Bound Check Exception",
|
||||||
@ -177,6 +178,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
|
|||||||
}
|
}
|
||||||
QEMU_FALLTHROUGH;
|
QEMU_FALLTHROUGH;
|
||||||
case EXCCODE_PIF:
|
case EXCCODE_PIF:
|
||||||
|
case EXCCODE_ADEF:
|
||||||
cause = cs->exception_index;
|
cause = cs->exception_index;
|
||||||
update_badinstr = 0;
|
update_badinstr = 0;
|
||||||
break;
|
break;
|
||||||
@ -184,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
|
|||||||
case EXCCODE_BRK:
|
case EXCCODE_BRK:
|
||||||
case EXCCODE_INE:
|
case EXCCODE_INE:
|
||||||
case EXCCODE_IPE:
|
case EXCCODE_IPE:
|
||||||
|
case EXCCODE_FPD:
|
||||||
case EXCCODE_FPE:
|
case EXCCODE_FPE:
|
||||||
case EXCCODE_BCE:
|
case EXCCODE_BCE:
|
||||||
env->CSR_BADV = env->pc;
|
env->CSR_BADV = env->pc;
|
||||||
@ -220,7 +223,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
|
|||||||
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
|
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
|
||||||
PC, (env->pc >> 2));
|
PC, (env->pc >> 2));
|
||||||
} else {
|
} else {
|
||||||
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause);
|
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE,
|
||||||
|
EXCODE_MCODE(cause));
|
||||||
|
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE,
|
||||||
|
EXCODE_SUBCODE(cause));
|
||||||
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
|
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
|
||||||
FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
|
FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
|
||||||
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
|
env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
|
||||||
@ -257,7 +263,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
|
|||||||
env->pc = env->CSR_TLBRENTRY;
|
env->pc = env->CSR_TLBRENTRY;
|
||||||
} else {
|
} else {
|
||||||
env->pc = env->CSR_EENTRY;
|
env->pc = env->CSR_EENTRY;
|
||||||
env->pc += cause * vec_size;
|
env->pc += EXCODE_MCODE(cause) * vec_size;
|
||||||
}
|
}
|
||||||
qemu_log_mask(CPU_LOG_INT,
|
qemu_log_mask(CPU_LOG_INT,
|
||||||
"%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
|
"%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
#include "cpu-csr.h"
|
||||||
|
|
||||||
#define IOCSRF_TEMP 0
|
#define IOCSRF_TEMP 0
|
||||||
#define IOCSRF_NODECNT 1
|
#define IOCSRF_NODECNT 1
|
||||||
@ -75,33 +76,37 @@ FIELD(FCSR0, CAUSE, 24, 5)
|
|||||||
#define FP_DIV0 8
|
#define FP_DIV0 8
|
||||||
#define FP_INVALID 16
|
#define FP_INVALID 16
|
||||||
|
|
||||||
|
#define EXCODE(code, subcode) ( ((subcode) << 6) | (code) )
|
||||||
|
#define EXCODE_MCODE(code) ( (code) & 0x3f )
|
||||||
|
#define EXCODE_SUBCODE(code) ( (code) >> 6 )
|
||||||
|
|
||||||
#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
|
#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */
|
||||||
#define EXCCODE_INT 0
|
#define EXCCODE_INT EXCODE(0, 0)
|
||||||
#define EXCCODE_PIL 1
|
#define EXCCODE_PIL EXCODE(1, 0)
|
||||||
#define EXCCODE_PIS 2
|
#define EXCCODE_PIS EXCODE(2, 0)
|
||||||
#define EXCCODE_PIF 3
|
#define EXCCODE_PIF EXCODE(3, 0)
|
||||||
#define EXCCODE_PME 4
|
#define EXCCODE_PME EXCODE(4, 0)
|
||||||
#define EXCCODE_PNR 5
|
#define EXCCODE_PNR EXCODE(5, 0)
|
||||||
#define EXCCODE_PNX 6
|
#define EXCCODE_PNX EXCODE(6, 0)
|
||||||
#define EXCCODE_PPI 7
|
#define EXCCODE_PPI EXCODE(7, 0)
|
||||||
#define EXCCODE_ADEF 8 /* Different exception subcode */
|
#define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */
|
||||||
#define EXCCODE_ADEM 8
|
#define EXCCODE_ADEM EXCODE(8, 1)
|
||||||
#define EXCCODE_ALE 9
|
#define EXCCODE_ALE EXCODE(9, 0)
|
||||||
#define EXCCODE_BCE 10
|
#define EXCCODE_BCE EXCODE(10, 0)
|
||||||
#define EXCCODE_SYS 11
|
#define EXCCODE_SYS EXCODE(11, 0)
|
||||||
#define EXCCODE_BRK 12
|
#define EXCCODE_BRK EXCODE(12, 0)
|
||||||
#define EXCCODE_INE 13
|
#define EXCCODE_INE EXCODE(13, 0)
|
||||||
#define EXCCODE_IPE 14
|
#define EXCCODE_IPE EXCODE(14, 0)
|
||||||
#define EXCCODE_FPD 15
|
#define EXCCODE_FPD EXCODE(15, 0)
|
||||||
#define EXCCODE_SXD 16
|
#define EXCCODE_SXD EXCODE(16, 0)
|
||||||
#define EXCCODE_ASXD 17
|
#define EXCCODE_ASXD EXCODE(17, 0)
|
||||||
#define EXCCODE_FPE 18 /* Different exception subcode */
|
#define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */
|
||||||
#define EXCCODE_VFPE 18
|
#define EXCCODE_VFPE EXCODE(18, 1)
|
||||||
#define EXCCODE_WPEF 19 /* Different exception subcode */
|
#define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */
|
||||||
#define EXCCODE_WPEM 19
|
#define EXCCODE_WPEM EXCODE(19, 1)
|
||||||
#define EXCCODE_BTD 20
|
#define EXCCODE_BTD EXCODE(20, 0)
|
||||||
#define EXCCODE_BTE 21
|
#define EXCCODE_BTE EXCODE(21, 0)
|
||||||
#define EXCCODE_DBP 26 /* Reserved subcode used for debug */
|
#define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */
|
||||||
|
|
||||||
/* cpucfg[0] bits */
|
/* cpucfg[0] bits */
|
||||||
FIELD(CPUCFG0, PRID, 0, 32)
|
FIELD(CPUCFG0, PRID, 0, 32)
|
||||||
@ -387,6 +392,13 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LoongArch CPUs hardware flags.
|
||||||
|
*/
|
||||||
|
#define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */
|
||||||
|
#define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */
|
||||||
|
#define HW_FLAGS_EUEN_FPE 0x04
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
|
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
|
||||||
target_ulong *pc,
|
target_ulong *pc,
|
||||||
target_ulong *cs_base,
|
target_ulong *cs_base,
|
||||||
@ -394,7 +406,8 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
|
|||||||
{
|
{
|
||||||
*pc = env->pc;
|
*pc = env->pc;
|
||||||
*cs_base = 0;
|
*cs_base = 0;
|
||||||
*flags = cpu_mmu_index(env, false);
|
*flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
|
||||||
|
*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loongarch_cpu_list(void);
|
void loongarch_cpu_list(void);
|
||||||
|
@ -3,9 +3,22 @@
|
|||||||
* Copyright (c) 2021 Loongson Technology Corporation Limited
|
* Copyright (c) 2021 Loongson Technology Corporation Limited
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
#define CHECK_FPE do { \
|
||||||
|
if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \
|
||||||
|
generate_exception(ctx, EXCCODE_FPD); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define CHECK_FPE
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool gen_fff(DisasContext *ctx, arg_fff *a,
|
static bool gen_fff(DisasContext *ctx, arg_fff *a,
|
||||||
void (*func)(TCGv, TCGv_env, TCGv, TCGv))
|
void (*func)(TCGv, TCGv_env, TCGv, TCGv))
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]);
|
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -13,6 +26,8 @@ static bool gen_fff(DisasContext *ctx, arg_fff *a,
|
|||||||
static bool gen_ff(DisasContext *ctx, arg_ff *a,
|
static bool gen_ff(DisasContext *ctx, arg_ff *a,
|
||||||
void (*func)(TCGv, TCGv_env, TCGv))
|
void (*func)(TCGv, TCGv_env, TCGv))
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]);
|
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -22,6 +37,9 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a,
|
|||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
TCGv_i32 tflag = tcg_constant_i32(flag);
|
TCGv_i32 tflag = tcg_constant_i32(flag);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj],
|
func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj],
|
||||||
cpu_fpr[a->fk], cpu_fpr[a->fa], tflag);
|
cpu_fpr[a->fk], cpu_fpr[a->fa], tflag);
|
||||||
return true;
|
return true;
|
||||||
@ -29,18 +47,24 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a,
|
|||||||
|
|
||||||
static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
|
static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31);
|
tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
|
static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63);
|
tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
|
static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31));
|
tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31));
|
||||||
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
||||||
return true;
|
return true;
|
||||||
@ -48,12 +72,16 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
|
|||||||
|
|
||||||
static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
|
static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63));
|
tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
|
static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000);
|
tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000);
|
||||||
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
||||||
return true;
|
return true;
|
||||||
@ -61,6 +89,8 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
|
|||||||
|
|
||||||
static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
|
static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL);
|
tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,13 @@ static uint32_t get_fcmp_flags(int cond)
|
|||||||
|
|
||||||
static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
|
static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
|
||||||
{
|
{
|
||||||
TCGv var = tcg_temp_new();
|
TCGv var;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
|
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
var = tcg_temp_new();
|
||||||
fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
|
fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
|
||||||
flags = get_fcmp_flags(a->fcond >> 1);
|
flags = get_fcmp_flags(a->fcond >> 1);
|
||||||
|
|
||||||
@ -41,9 +44,13 @@ static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
|
|||||||
|
|
||||||
static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
|
static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
|
||||||
{
|
{
|
||||||
TCGv var = tcg_temp_new();
|
TCGv var;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
|
void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
var = tcg_temp_new();
|
||||||
fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
|
fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
|
||||||
flags = get_fcmp_flags(a->fcond >> 1);
|
flags = get_fcmp_flags(a->fcond >> 1);
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
|
|||||||
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv temp = NULL;
|
TCGv temp = NULL;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
if (a->imm) {
|
if (a->imm) {
|
||||||
temp = tcg_temp_new();
|
temp = tcg_temp_new();
|
||||||
tcg_gen_addi_tl(temp, addr, a->imm);
|
tcg_gen_addi_tl(temp, addr, a->imm);
|
||||||
@ -36,6 +38,8 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
|
|||||||
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv temp = NULL;
|
TCGv temp = NULL;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
if (a->imm) {
|
if (a->imm) {
|
||||||
temp = tcg_temp_new();
|
temp = tcg_temp_new();
|
||||||
tcg_gen_addi_tl(temp, addr, a->imm);
|
tcg_gen_addi_tl(temp, addr, a->imm);
|
||||||
@ -54,8 +58,11 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
maybe_nanbox_load(cpu_fpr[a->fd], mop);
|
maybe_nanbox_load(cpu_fpr[a->fd], mop);
|
||||||
@ -68,8 +75,11 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
tcg_temp_free(addr);
|
tcg_temp_free(addr);
|
||||||
@ -81,8 +91,11 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
gen_helper_asrtgt_d(cpu_env, src1, src2);
|
gen_helper_asrtgt_d(cpu_env, src1, src2);
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
@ -96,8 +109,11 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
gen_helper_asrtgt_d(cpu_env, src1, src2);
|
gen_helper_asrtgt_d(cpu_env, src1, src2);
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
@ -110,8 +126,11 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
gen_helper_asrtle_d(cpu_env, src1, src2);
|
gen_helper_asrtle_d(cpu_env, src1, src2);
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
@ -125,8 +144,11 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop)
|
|||||||
{
|
{
|
||||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
|
||||||
TCGv addr = tcg_temp_new();
|
TCGv addr;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
gen_helper_asrtle_d(cpu_env, src1, src2);
|
gen_helper_asrtle_d(cpu_env, src1, src2);
|
||||||
tcg_gen_add_tl(addr, src1, src2);
|
tcg_gen_add_tl(addr, src1, src2);
|
||||||
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
|
||||||
|
@ -10,8 +10,11 @@ static const uint32_t fcsr_mask[4] = {
|
|||||||
static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
|
static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
|
||||||
{
|
{
|
||||||
TCGv zero = tcg_constant_tl(0);
|
TCGv zero = tcg_constant_tl(0);
|
||||||
TCGv cond = tcg_temp_new();
|
TCGv cond;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
cond = tcg_temp_new();
|
||||||
tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca]));
|
tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca]));
|
||||||
tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero,
|
tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero,
|
||||||
cpu_fpr[a->fj], cpu_fpr[a->fk]);
|
cpu_fpr[a->fj], cpu_fpr[a->fk]);
|
||||||
@ -26,6 +29,8 @@ static bool gen_f2f(DisasContext *ctx, arg_ff *a,
|
|||||||
TCGv dest = cpu_fpr[a->fd];
|
TCGv dest = cpu_fpr[a->fd];
|
||||||
TCGv src = cpu_fpr[a->fj];
|
TCGv src = cpu_fpr[a->fj];
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(dest, src);
|
func(dest, src);
|
||||||
if (nanbox) {
|
if (nanbox) {
|
||||||
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
|
||||||
@ -39,6 +44,8 @@ static bool gen_r2f(DisasContext *ctx, arg_fr *a,
|
|||||||
{
|
{
|
||||||
TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(cpu_fpr[a->fd], src);
|
func(cpu_fpr[a->fd], src);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -48,6 +55,8 @@ static bool gen_f2r(DisasContext *ctx, arg_rf *a,
|
|||||||
{
|
{
|
||||||
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
func(dest, cpu_fpr[a->fj]);
|
func(dest, cpu_fpr[a->fj]);
|
||||||
gen_set_gpr(a->rd, dest, EXT_NONE);
|
gen_set_gpr(a->rd, dest, EXT_NONE);
|
||||||
|
|
||||||
@ -59,6 +68,8 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a)
|
|||||||
uint32_t mask = fcsr_mask[a->fcsrd];
|
uint32_t mask = fcsr_mask[a->fcsrd];
|
||||||
TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
|
TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
if (mask == UINT32_MAX) {
|
if (mask == UINT32_MAX) {
|
||||||
tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0));
|
tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0));
|
||||||
} else {
|
} else {
|
||||||
@ -90,6 +101,8 @@ static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a)
|
|||||||
{
|
{
|
||||||
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0));
|
tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0));
|
||||||
tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]);
|
tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]);
|
||||||
gen_set_gpr(a->rd, dest, EXT_NONE);
|
gen_set_gpr(a->rd, dest, EXT_NONE);
|
||||||
@ -114,8 +127,11 @@ static void gen_movfrh2gr_s(TCGv dest, TCGv src)
|
|||||||
|
|
||||||
static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
|
static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
|
||||||
{
|
{
|
||||||
TCGv t0 = tcg_temp_new();
|
TCGv t0;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
t0 = tcg_temp_new();
|
||||||
tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1);
|
tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1);
|
||||||
tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
|
tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
|
||||||
tcg_temp_free(t0);
|
tcg_temp_free(t0);
|
||||||
@ -125,6 +141,8 @@ static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
|
|||||||
|
|
||||||
static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
|
static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env,
|
tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env,
|
||||||
offsetof(CPULoongArchState, cf[a->cj & 0x7]));
|
offsetof(CPULoongArchState, cf[a->cj & 0x7]));
|
||||||
return true;
|
return true;
|
||||||
@ -132,8 +150,11 @@ static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
|
|||||||
|
|
||||||
static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
|
static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
|
||||||
{
|
{
|
||||||
TCGv t0 = tcg_temp_new();
|
TCGv t0;
|
||||||
|
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
|
t0 = tcg_temp_new();
|
||||||
tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1);
|
tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1);
|
||||||
tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
|
tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
|
||||||
tcg_temp_free(t0);
|
tcg_temp_free(t0);
|
||||||
@ -143,6 +164,8 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
|
|||||||
|
|
||||||
static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a)
|
static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a)
|
||||||
{
|
{
|
||||||
|
CHECK_FPE;
|
||||||
|
|
||||||
tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env,
|
tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env,
|
||||||
offsetof(CPULoongArchState, cf[a->cj & 0x7]));
|
offsetof(CPULoongArchState, cf[a->cj & 0x7]));
|
||||||
return true;
|
return true;
|
||||||
|
@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = {
|
|||||||
|
|
||||||
static bool check_plv(DisasContext *ctx)
|
static bool check_plv(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->base.tb->flags == MMU_USER_IDX) {
|
if (ctx->mem_idx == MMU_USER_IDX) {
|
||||||
generate_exception(ctx, EXCCODE_IPE);
|
generate_exception(ctx, EXCCODE_IPE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -14,54 +14,57 @@
|
|||||||
#include "exec/cpu_ldst.h"
|
#include "exec/cpu_ldst.h"
|
||||||
#include "tcg/tcg-ldst.h"
|
#include "tcg/tcg-ldst.h"
|
||||||
|
|
||||||
|
#define GET_MEMTXATTRS(cas) \
|
||||||
|
((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index})
|
||||||
|
|
||||||
uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr)
|
uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr)
|
||||||
{
|
{
|
||||||
return address_space_ldub(&env->address_space_iocsr, r_addr,
|
return address_space_ldub(&env->address_space_iocsr, r_addr,
|
||||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr)
|
uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr)
|
||||||
{
|
{
|
||||||
return address_space_lduw(&env->address_space_iocsr, r_addr,
|
return address_space_lduw(&env->address_space_iocsr, r_addr,
|
||||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr)
|
uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr)
|
||||||
{
|
{
|
||||||
return address_space_ldl(&env->address_space_iocsr, r_addr,
|
return address_space_ldl(&env->address_space_iocsr, r_addr,
|
||||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr)
|
uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr)
|
||||||
{
|
{
|
||||||
return address_space_ldq(&env->address_space_iocsr, r_addr,
|
return address_space_ldq(&env->address_space_iocsr, r_addr,
|
||||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr,
|
void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr,
|
||||||
target_ulong val)
|
target_ulong val)
|
||||||
{
|
{
|
||||||
address_space_stb(&env->address_space_iocsr, w_addr,
|
address_space_stb(&env->address_space_iocsr, w_addr,
|
||||||
val, MEMTXATTRS_UNSPECIFIED, NULL);
|
val, GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr,
|
void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr,
|
||||||
target_ulong val)
|
target_ulong val)
|
||||||
{
|
{
|
||||||
address_space_stw(&env->address_space_iocsr, w_addr,
|
address_space_stw(&env->address_space_iocsr, w_addr,
|
||||||
val, MEMTXATTRS_UNSPECIFIED, NULL);
|
val, GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr,
|
void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr,
|
||||||
target_ulong val)
|
target_ulong val)
|
||||||
{
|
{
|
||||||
address_space_stl(&env->address_space_iocsr, w_addr,
|
address_space_stl(&env->address_space_iocsr, w_addr,
|
||||||
val, MEMTXATTRS_UNSPECIFIED, NULL);
|
val, GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr,
|
void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr,
|
||||||
target_ulong val)
|
target_ulong val)
|
||||||
{
|
{
|
||||||
address_space_stq(&env->address_space_iocsr, w_addr,
|
address_space_stq(&env->address_space_iocsr, w_addr,
|
||||||
val, MEMTXATTRS_UNSPECIFIED, NULL);
|
val, GET_MEMTXATTRS(env), NULL);
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,8 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
|
|||||||
switch (tlb_error) {
|
switch (tlb_error) {
|
||||||
default:
|
default:
|
||||||
case TLBRET_BADADDR:
|
case TLBRET_BADADDR:
|
||||||
cs->exception_index = EXCCODE_ADEM;
|
cs->exception_index = access_type == MMU_INST_FETCH
|
||||||
|
? EXCCODE_ADEF : EXCCODE_ADEM;
|
||||||
break;
|
break;
|
||||||
case TLBRET_NOMATCH:
|
case TLBRET_NOMATCH:
|
||||||
/* No TLB match for a mapped address */
|
/* No TLB match for a mapped address */
|
||||||
@ -643,7 +644,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||||||
CPULoongArchState *env = &cpu->env;
|
CPULoongArchState *env = &cpu->env;
|
||||||
hwaddr physical;
|
hwaddr physical;
|
||||||
int prot;
|
int prot;
|
||||||
int ret = TLBRET_BADADDR;
|
int ret;
|
||||||
|
|
||||||
/* Data access */
|
/* Data access */
|
||||||
ret = get_physical_address(env, &physical, &prot, address,
|
ret = get_physical_address(env, &physical, &prot, address,
|
||||||
|
@ -75,7 +75,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
|
|||||||
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
||||||
|
|
||||||
ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
|
ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
|
||||||
ctx->mem_idx = ctx->base.tb->flags;
|
if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) {
|
||||||
|
ctx->mem_idx = ctx->base.tb->flags & HW_FLAGS_PLV_MASK;
|
||||||
|
} else {
|
||||||
|
ctx->mem_idx = MMU_DA_IDX;
|
||||||
|
}
|
||||||
|
|
||||||
/* Bound the number of insns to execute to those left on the page. */
|
/* Bound the number of insns to execute to those left on the page. */
|
||||||
bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
|
bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
|
||||||
|
Loading…
Reference in New Issue
Block a user