Merge remote-tracking branch 'qemu-kvm/memory/urgent' into staging

* qemu-kvm/memory/urgent: (42 commits)
  memory: check for watchpoints when getting code ram_addr
  exec: fix write tlb entry misused as iotlb
  Sparc: avoid AREG0 wrappers for memory access helpers
  Sparc: avoid AREG0 for memory access helpers
  TCG: add 5 arg helpers to def-helper.h
  softmmu templates: optionally pass CPUState to memory access functions
  i386: Remove REGPARM
  sparc64: implement PCI and ISA irqs
  sparc: reset CPU state on reset
  apb: use normal PCI device header for PBM device
  w64: Fix data type of next_tb and tcg_qemu_tb_exec
  softfloat: fix for C99
  vmstate: fix varrays with uint32_t indexes
  Fix large memory chunks allocation with tcg_malloc.
  hw/pxa2xx.c: Fix handling of pxa2xx_i2c variable offset within region
  hw/pxa2xx_lcd.c: drop target_phys_addr_t usage in device state
  hw/pxa2xx_dma.c: drop target_phys_addr_t usage in device state
  ARM: Remove unnecessary subpage workarounds
  malta: Fix display for LED array
  malta: Use symbolic hardware addresses
  ...
This commit is contained in:
Anthony Liguori 2012-03-19 08:51:50 -05:00
commit b8b3e75609
72 changed files with 1599 additions and 870 deletions

View File

@ -80,7 +80,10 @@ libobj-y = exec.o translate-all.o cpu-exec.o translate.o
libobj-y += tcg/tcg.o tcg/optimize.o
libobj-$(CONFIG_TCG_INTERPRETER) += tci.o
libobj-y += fpu/softfloat.o
libobj-y += op_helper.o helper.o
ifneq ($(TARGET_BASE_ARCH), sparc)
libobj-y += op_helper.o
endif
libobj-y += helper.o
ifeq ($(TARGET_BASE_ARCH), i386)
libobj-y += cpuid.o
endif
@ -101,9 +104,12 @@ tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci
$(libobj-y): $(GENERATED_HEADERS)
# HELPER_CFLAGS is used for all the code compiled with static register
# HELPER_CFLAGS is used for all the legacy code compiled with static register
# variables
op_helper.o ldst_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
ifneq ($(TARGET_BASE_ARCH), sparc)
op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
endif
user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
# Note: this is a workaround. The real fix is to avoid compiling
# cpu_signal_handler() in user-exec.c.

7
configure vendored
View File

@ -3606,6 +3606,13 @@ case "$target_arch2" in
exit 1
;;
esac
case "$target_arch2" in
sparc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak
echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak
echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak

View File

@ -259,12 +259,21 @@ extern unsigned long reserved_va;
#define stfl(p, v) stfl_raw(p, v)
#define stfq(p, v) stfq_raw(p, v)
#ifndef CONFIG_TCG_PASS_AREG0
#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
#define lduw_code(p) lduw_raw(p)
#define ldsw_code(p) ldsw_raw(p)
#define ldl_code(p) ldl_raw(p)
#define ldq_code(p) ldq_raw(p)
#else
#define cpu_ldub_code(env1, p) ldub_raw(p)
#define cpu_ldsb_code(env1, p) ldsb_raw(p)
#define cpu_lduw_code(env1, p) lduw_raw(p)
#define cpu_ldsw_code(env1, p) ldsw_raw(p)
#define cpu_ldl_code(env1, p) ldl_raw(p)
#define cpu_ldq_code(env1, p) ldq_raw(p)
#endif
#define ldub_kernel(p) ldub_raw(p)
#define ldsb_kernel(p) ldsb_raw(p)

View File

@ -55,7 +55,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
TranslationBlock *orig_tb)
{
unsigned long next_tb;
tcg_target_ulong next_tb;
TranslationBlock *tb;
/* Should never happen.
@ -186,7 +186,7 @@ int cpu_exec(CPUArchState *env)
int ret, interrupt_request;
TranslationBlock *tb;
uint8_t *tc_ptr;
unsigned long next_tb;
tcg_target_ulong next_tb;
if (env->halted) {
if (!cpu_has_work(env)) {
@ -565,7 +565,7 @@ int cpu_exec(CPUArchState *env)
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
tb = (TranslationBlock *)(long)(next_tb & ~3);
tb = (TranslationBlock *)(next_tb & ~3);
/* Restore PC. */
cpu_pc_from_tb(env, tb);
insns_left = env->icount_decr.u32;

View File

@ -118,6 +118,8 @@
DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
#define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
#define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
#endif /* DEF_HELPER_H */
@ -140,6 +142,10 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
dh_ctype(t4));
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
dh_ctype(t4), dh_ctype(t5));
#undef GEN_HELPER
#define GEN_HELPER -1
@ -203,6 +209,22 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1
tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
}
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
{ \
TCGArg args[5]; \
int sizemask = 0; \
dh_sizemask(ret, 0); \
dh_arg(t1, 1); \
dh_arg(t2, 2); \
dh_arg(t3, 3); \
dh_arg(t4, 4); \
dh_arg(t5, 5); \
tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 5, args); \
}
#undef GEN_HELPER
#define GEN_HELPER -1
@ -224,6 +246,9 @@ DEF_HELPER_FLAGS_0(name, flags, ret)
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
DEF_HELPER_FLAGS_0(name, flags, ret)
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
DEF_HELPER_FLAGS_0(name, flags, ret)
#undef GEN_HELPER
#define GEN_HELPER -1
@ -235,6 +260,7 @@ DEF_HELPER_FLAGS_0(name, flags, ret)
#undef DEF_HELPER_FLAGS_2
#undef DEF_HELPER_FLAGS_3
#undef DEF_HELPER_FLAGS_4
#undef DEF_HELPER_FLAGS_5
#undef GEN_HELPER
#endif

View File

@ -312,7 +312,9 @@ void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
#define ACCESS_TYPE (NB_MMU_MODES + 1)
#define MEMSUFFIX _code
#ifndef CONFIG_TCG_PASS_AREG0
#define env cpu_single_env
#endif
#define DATA_SIZE 1
#include "softmmu_header.h"

18
exec.c
View File

@ -2031,14 +2031,19 @@ static void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG);
}
static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe)
{
return (tlbe->addr_write & (TLB_INVALID_MASK|TLB_MMIO|TLB_NOTDIRTY)) == 0;
}
static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
unsigned long start, unsigned long length)
{
unsigned long addr;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
if (tlb_is_dirty_ram(tlb_entry)) {
addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((addr - start) < length) {
tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
tlb_entry->addr_write |= TLB_NOTDIRTY;
}
}
}
@ -2091,7 +2096,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
ram_addr_t ram_addr;
void *p;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
if (tlb_is_dirty_ram(tlb_entry)) {
p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
+ tlb_entry->addend);
ram_addr = qemu_ram_addr_from_host_nofail(p);
@ -4595,12 +4600,17 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
mmu_idx = cpu_mmu_index(env1);
if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
(addr & TARGET_PAGE_MASK))) {
#ifdef CONFIG_TCG_PASS_AREG0
cpu_ldub_code(env1, addr);
#else
ldub_code(addr);
#endif
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(pd);
if (mr != &io_mem_ram && mr != &io_mem_rom
&& mr != &io_mem_notdirty && !mr->rom_device) {
&& mr != &io_mem_notdirty && !mr->rom_device
&& mr != &io_mem_watch) {
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
#else

View File

@ -89,8 +89,8 @@ const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
#endif
const floatx80 floatx80_default_nan = make_floatx80(floatx80_default_nan_high,
floatx80_default_nan_low);
const floatx80 floatx80_default_nan
= make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low);
/*----------------------------------------------------------------------------
| The pattern for a default generated quadruple-precision NaN. The `high' and
@ -104,8 +104,8 @@ const floatx80 floatx80_default_nan = make_floatx80(floatx80_default_nan_high,
#define float128_default_nan_low LIT64( 0x0000000000000000 )
#endif
const float128 float128_default_nan = make_float128(float128_default_nan_high,
float128_default_nan_low);
const float128 float128_default_nan
= make_float128_init(float128_default_nan_high, float128_default_nan_low);
/*----------------------------------------------------------------------------
| Raises the exceptions specified by `flags'. Floating-point traps can be

View File

@ -129,6 +129,7 @@ typedef struct {
uint16_t high;
} floatx80;
#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
#define make_floatx80_init(exp, mant) { .low = mant, .high = exp }
typedef struct {
#ifdef HOST_WORDS_BIGENDIAN
uint64_t high, low;
@ -137,6 +138,7 @@ typedef struct {
#endif
} float128;
#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ })
#define make_float128_init(high_, low_) { .high = high_, .low = low_ }
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point underflow tininess-detection mode.

View File

@ -66,6 +66,8 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
#define RESET_WCMASK 0x98000000
#define RESET_WMASK 0x60000000
#define MAX_IVEC 0x30
typedef struct APBState {
SysBusDevice busdev;
PCIBus *bus;
@ -77,7 +79,8 @@ typedef struct APBState {
uint32_t pci_control[16];
uint32_t pci_irq_map[8];
uint32_t obio_irq_map[32];
qemu_irq pci_irqs[32];
qemu_irq *pbm_irqs;
qemu_irq *ivec_irqs;
uint32_t reset_control;
unsigned int nr_resets;
} APBState;
@ -87,7 +90,7 @@ static void apb_config_writel (void *opaque, target_phys_addr_t addr,
{
APBState *s = opaque;
APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
switch (addr & 0xffff) {
case 0x30 ... 0x4f: /* DMA error registers */
@ -104,6 +107,12 @@ static void apb_config_writel (void *opaque, target_phys_addr_t addr,
s->pci_irq_map[(addr & 0x3f) >> 3] |= val & ~PBM_PCI_IMR_MASK;
}
break;
case 0x1000 ... 0x1080: /* OBIO interrupt control */
if (addr & 4) {
s->obio_irq_map[(addr & 0xff) >> 3] &= PBM_PCI_IMR_MASK;
s->obio_irq_map[(addr & 0xff) >> 3] |= val & ~PBM_PCI_IMR_MASK;
}
break;
case 0x2000 ... 0x202f: /* PCI control */
s->pci_control[(addr & 0x3f) >> 2] = val;
break;
@ -154,6 +163,13 @@ static uint64_t apb_config_readl (void *opaque,
val = 0;
}
break;
case 0x1000 ... 0x1080: /* OBIO interrupt control */
if (addr & 4) {
val = s->obio_irq_map[(addr & 0xff) >> 3];
} else {
val = 0;
}
break;
case 0x2000 ... 0x202f: /* PCI control */
val = s->pci_control[(addr & 0x3f) >> 2];
break;
@ -190,7 +206,7 @@ static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
APBState *s = opaque;
val = qemu_bswap_len(val, size);
APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
pci_data_write(s->bus, addr, val, size);
}
@ -280,10 +296,19 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
if (irq_num < 32) {
if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
qemu_set_irq(s->pci_irqs[irq_num], level);
qemu_set_irq(s->ivec_irqs[irq_num], level);
} else {
APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
qemu_irq_lower(s->pci_irqs[irq_num]);
qemu_irq_lower(s->ivec_irqs[irq_num]);
}
} else {
/* OBIO IRQ map onto the next 16 INO. */
if (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED) {
APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
qemu_set_irq(s->ivec_irqs[irq_num], level);
} else {
APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
qemu_irq_lower(s->ivec_irqs[irq_num]);
}
}
}
@ -316,12 +341,12 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
PCIBus *pci_apb_init(target_phys_addr_t special_base,
target_phys_addr_t mem_base,
qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
qemu_irq **pbm_irqs)
{
DeviceState *dev;
SysBusDevice *s;
APBState *d;
unsigned int i;
PCIDevice *pci_dev;
PCIBridge *br;
@ -346,9 +371,8 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
get_system_io(),
0, 32);
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}
*pbm_irqs = d->pbm_irqs;
d->ivec_irqs = ivec_irqs;
pci_create_simple(d->bus, 0, "pbm-pci");
@ -402,9 +426,7 @@ static int pci_pbm_init_device(SysBusDevice *dev)
for (i = 0; i < 8; i++) {
s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
}
for (i = 0; i < 32; i++) {
sysbus_init_irq(dev, &s->pci_irqs[i]);
}
s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
/* apb_config */
memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
@ -444,7 +466,6 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_SUN;
k->device_id = PCI_DEVICE_ID_SUN_SABRE;
k->class_id = PCI_CLASS_BRIDGE_HOST;
k->is_bridge = 1;
}
static TypeInfo pbm_pci_host_info = {

View File

@ -5,5 +5,6 @@
PCIBus *pci_apb_init(target_phys_addr_t special_base,
target_phys_addr_t mem_base,
qemu_irq *pic, PCIBus **bus2, PCIBus **bus3);
qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
qemu_irq **pbm_irqs);
#endif

View File

@ -42,7 +42,6 @@ static uint64_t mpcore_scu_read(void *opaque, target_phys_addr_t offset,
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
int id;
offset &= 0xff;
/* SCU */
switch (offset) {
case 0x00: /* Control. */
@ -63,7 +62,6 @@ static void mpcore_scu_write(void *opaque, target_phys_addr_t offset,
uint64_t value, unsigned size)
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
offset &= 0xff;
/* SCU */
switch (offset) {
case 0: /* Control register. */

View File

@ -658,14 +658,14 @@ static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
gic_state *s = (gic_state *)opaque;
return gic_cpu_read(s, gic_get_current_cpu(), addr & 0xff);
return gic_cpu_read(s, gic_get_current_cpu(), addr);
}
static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
uint64_t value, unsigned size)
{
gic_state *s = (gic_state *)opaque;
gic_cpu_write(s, gic_get_current_cpu(), addr & 0xff, value);
gic_cpu_write(s, gic_get_current_cpu(), addr, value);
}
/* Wrappers to read/write the GIC CPU interface for a specific CPU.
@ -677,7 +677,7 @@ static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,
gic_state **backref = (gic_state **)opaque;
gic_state *s = *backref;
int id = (backref - s->backref);
return gic_cpu_read(s, id, addr & 0xff);
return gic_cpu_read(s, id, addr);
}
static void gic_do_cpu_write(void *opaque, target_phys_addr_t addr,
@ -686,7 +686,7 @@ static void gic_do_cpu_write(void *opaque, target_phys_addr_t addr,
gic_state **backref = (gic_state **)opaque;
gic_state *s = *backref;
int id = (backref - s->backref);
gic_cpu_write(s, id, addr & 0xff, value);
gic_cpu_write(s, id, addr, value);
}
static const MemoryRegionOps gic_thiscpu_ops = {

View File

@ -97,7 +97,6 @@ static uint64_t timerblock_read(void *opaque, target_phys_addr_t addr,
{
timerblock *tb = (timerblock *)opaque;
int64_t val;
addr &= 0x1f;
switch (addr) {
case 0: /* Load */
return tb->load;
@ -126,7 +125,6 @@ static void timerblock_write(void *opaque, target_phys_addr_t addr,
{
timerblock *tb = (timerblock *)opaque;
int64_t old;
addr &= 0x1f;
switch (addr) {
case 0: /* Load */
tb->load = value;

View File

@ -55,6 +55,13 @@
#define ENVP_NB_ENTRIES 16
#define ENVP_ENTRY_SIZE 256
/* Hardware addresses */
#define FLASH_ADDRESS 0x1e000000ULL
#define FPGA_ADDRESS 0x1f000000ULL
#define RESET_ADDRESS 0x1fc00000ULL
#define FLASH_SIZE 0x400000
#define MAX_IDE_BUS 2
typedef struct {
@ -331,9 +338,9 @@ static void malta_fpga_write(void *opaque, target_phys_addr_t addr,
break;
/* LEDBAR Register */
/* XXX: implement a 8-LED array */
case 0x00408:
s->leds = val & 0xff;
malta_fpga_update_display(s);
break;
/* ASCIIWORD Register */
@ -777,7 +784,7 @@ void mips_malta_init (ram_addr_t ram_size,
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
target_long bios_size;
target_long bios_size = FLASH_SIZE;
int64_t kernel_entry;
PCIBus *pci_bus;
ISABus *isa_bus;
@ -791,7 +798,7 @@ void mips_malta_init (ram_addr_t ram_size,
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
DriveInfo *fd[MAX_FD];
int fl_idx = 0;
int fl_sectors = 0;
int fl_sectors = bios_size >> 16;
int be;
DeviceState *dev = qdev_create(NULL, "mips-malta");
@ -847,19 +854,26 @@ void mips_malta_init (ram_addr_t ram_size,
be = 0;
#endif
/* FPGA */
malta_fpga_init(system_memory, 0x1f000000LL, env->irq[2], serial_hds[2]);
malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]);
/* Load firmware in flash / BIOS unless we boot directly into a kernel. */
/* Load firmware in flash / BIOS. */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
#ifdef DEBUG_BOARD_INIT
if (dinfo) {
printf("Register parallel flash %d size " TARGET_FMT_lx " at "
"addr %08llx '%s' %x\n",
fl_idx, bios_size, FLASH_ADDRESS,
bdrv_get_device_name(dinfo->bdrv), fl_sectors);
}
#endif
fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
65536, fl_sectors,
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
bios = pflash_cfi01_get_memory(fl);
fl_idx++;
if (kernel_filename) {
/* Write a small bootloader to the flash location. */
bios = g_new(MemoryRegion, 1);
memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE);
vmstate_register_ram_global(bios);
memory_region_set_readonly(bios, true);
memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
/* Map the bios at two physical locations, as on the real board. */
memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias);
loaderparams.ram_size = ram_size;
loaderparams.kernel_filename = kernel_filename;
loaderparams.kernel_cmdline = kernel_cmdline;
@ -867,45 +881,15 @@ void mips_malta_init (ram_addr_t ram_size,
kernel_entry = load_kernel();
write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
} else {
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
if (dinfo) {
/* Load firmware from flash. */
bios_size = 0x400000;
fl_sectors = bios_size >> 16;
#ifdef DEBUG_BOARD_INIT
printf("Register parallel flash %d size " TARGET_FMT_lx " at "
"addr %08llx '%s' %x\n",
fl_idx, bios_size, 0x1e000000LL,
bdrv_get_device_name(dinfo->bdrv), fl_sectors);
#endif
fl = pflash_cfi01_register(0x1e000000LL,
NULL, "mips_malta.bios", BIOS_SIZE,
dinfo->bdrv, 65536, fl_sectors,
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
bios = pflash_cfi01_get_memory(fl);
/* Map the bios at two physical locations, as on the real board. */
memory_region_init_alias(bios_alias, "bios.1fc",
bios, 0, BIOS_SIZE);
memory_region_add_subregion(system_memory, 0x1fc00000LL,
bios_alias);
fl_idx++;
} else {
bios = g_new(MemoryRegion, 1);
memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE);
vmstate_register_ram_global(bios);
memory_region_set_readonly(bios, true);
memory_region_init_alias(bios_alias, "bios.1fc",
bios, 0, BIOS_SIZE);
/* Map the bios at two physical locations, as on the real board. */
memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
memory_region_add_subregion(system_memory, 0x1fc00000LL,
bios_alias);
/* Load firmware from flash. */
if (!dinfo) {
/* Load a BIOS image. */
if (bios_name == NULL)
if (bios_name == NULL) {
bios_name = BIOS_FILENAME;
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = load_image_targphys(filename, 0x1fc00000LL,
bios_size = load_image_targphys(filename, FLASH_ADDRESS,
BIOS_SIZE);
g_free(filename);
} else {
@ -932,6 +916,10 @@ void mips_malta_init (ram_addr_t ram_size,
#endif
}
/* Map the BIOS at a 2nd physical location, as on the real board. */
memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias);
/* Board ID = 0x420 (Malta Board with CoreLV)
XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
map to the board ID. */

View File

@ -45,7 +45,6 @@ struct n800_s {
uint32_t (*txrx)(void *opaque, uint32_t value, int len);
uWireSlave *chip;
} ts;
i2c_bus *i2c;
int keymap[0x80];
DeviceState *kbd;
@ -194,12 +193,10 @@ static void n8x0_i2c_setup(struct n800_s *s)
{
DeviceState *dev;
qemu_irq tmp_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TMP105_GPIO);
/* Attach the CPU on one end of our I2C bus. */
s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
i2c_bus *i2c = omap_i2c_bus(s->cpu->i2c[0]);
/* Attach a menelaus PM chip */
dev = i2c_create_slave(s->i2c, "twl92230", N8X0_MENELAUS_ADDR);
dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
qdev_connect_gpio_out(dev, 3,
qdev_get_gpio_in(s->cpu->ih[0],
OMAP_INT_24XX_SYS_NIRQ));
@ -207,7 +204,7 @@ static void n8x0_i2c_setup(struct n800_s *s)
qemu_system_powerdown = qdev_get_gpio_in(dev, 3);
/* Attach a TMP105 PM chip (A0 wired to ground) */
dev = i2c_create_slave(s->i2c, "tmp105", N8X0_TMP105_ADDR);
dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
qdev_connect_gpio_out(dev, 0, tmp_irq);
}
@ -391,7 +388,8 @@ static void n810_kbd_setup(struct n800_s *s)
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
s->kbd = i2c_create_slave(s->i2c, "lm8323", N810_LM8323_ADDR);
s->kbd = i2c_create_slave(omap_i2c_bus(s->cpu->i2c[0]),
"lm8323", N810_LM8323_ADDR);
qdev_connect_gpio_out(s->kbd, 0, kbd_irq);
}

View File

@ -764,16 +764,7 @@ void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
void omap_mmc_enable(struct omap_mmc_s *s, int enable);
/* omap_i2c.c */
struct omap_i2c_s;
struct omap_i2c_s *omap_i2c_init(MemoryRegion *sysmem,
target_phys_addr_t base,
qemu_irq irq,
qemu_irq *dma,
omap_clk clk);
struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk);
void omap_i2c_reset(struct omap_i2c_s *s);
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c);
# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
@ -867,7 +858,7 @@ struct omap_mpu_state_s {
struct omap_pwl_s *pwl;
struct omap_pwt_s *pwt;
struct omap_i2c_s *i2c[2];
DeviceState *i2c[2];
struct omap_rtc_s *rtc;

View File

@ -3694,7 +3694,6 @@ static void omap1_mpu_reset(void *opaque)
omap_uwire_reset(mpu->microwire);
omap_pwl_reset(mpu->pwl);
omap_pwt_reset(mpu->pwt);
omap_i2c_reset(mpu->i2c[0]);
omap_rtc_reset(mpu->rtc);
omap_mcbsp_reset(mpu->mcbsp1);
omap_mcbsp_reset(mpu->mcbsp2);
@ -3993,9 +3992,15 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
omap_findclk(s, "armxor_ck"));
s->i2c[0] = omap_i2c_init(system_memory, 0xfffb3800,
qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C),
&s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
s->i2c[0] = qdev_create(NULL, "omap_i2c");
qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
qdev_init_nofail(s->i2c[0]);
busdev = sysbus_from_qdev(s->i2c[0]);
sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
sysbus_mmio_map(busdev, 0, 0xfffb3800);
s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),

View File

@ -2222,8 +2222,6 @@ static void omap2_mpu_reset(void *opaque)
omap_mmc_reset(mpu->mmc);
omap_mcspi_reset(mpu->mcspi[0]);
omap_mcspi_reset(mpu->mcspi[1]);
omap_i2c_reset(mpu->i2c[0]);
omap_i2c_reset(mpu->i2c[1]);
cpu_state_reset(mpu->env);
}
@ -2395,16 +2393,29 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
omap_findclk(s, "clk32-kHz"),
omap_findclk(s, "core_l4_iclk"));
s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ),
&s->drq[OMAP24XX_DMA_I2C1_TX],
omap_findclk(s, "i2c1.fclk"),
omap_findclk(s, "i2c1.iclk"));
s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ),
&s->drq[OMAP24XX_DMA_I2C2_TX],
omap_findclk(s, "i2c2.fclk"),
omap_findclk(s, "i2c2.iclk"));
s->i2c[0] = qdev_create(NULL, "omap_i2c");
qdev_prop_set_uint8(s->i2c[0], "revision", 0x34);
qdev_prop_set_ptr(s->i2c[0], "iclk", omap_findclk(s, "i2c1.iclk"));
qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "i2c1.fclk"));
qdev_init_nofail(s->i2c[0]);
busdev = sysbus_from_qdev(s->i2c[0]);
sysbus_connect_irq(busdev, 0,
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ));
sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C1_TX]);
sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C1_RX]);
sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 5), 0));
s->i2c[1] = qdev_create(NULL, "omap_i2c");
qdev_prop_set_uint8(s->i2c[1], "revision", 0x34);
qdev_prop_set_ptr(s->i2c[1], "iclk", omap_findclk(s, "i2c2.iclk"));
qdev_prop_set_ptr(s->i2c[1], "fclk", omap_findclk(s, "i2c2.fclk"));
qdev_init_nofail(s->i2c[1]);
busdev = sysbus_from_qdev(s->i2c[1]);
sysbus_connect_irq(busdev, 0,
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ));
sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C2_TX]);
sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C2_RX]);
sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 6), 0));
s->gpio = qdev_create(NULL, "omap2-gpio");
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);

View File

@ -19,14 +19,20 @@
#include "hw.h"
#include "i2c.h"
#include "omap.h"
#include "sysbus.h"
struct omap_i2c_s {
typedef struct OMAPI2CState {
SysBusDevice busdev;
MemoryRegion iomem;
qemu_irq irq;
qemu_irq drq[2];
i2c_bus *bus;
uint8_t revision;
void *iclk;
void *fclk;
uint8_t mask;
uint16_t stat;
uint16_t dma;
@ -40,12 +46,12 @@ struct omap_i2c_s {
uint8_t divider;
uint8_t times[2];
uint16_t test;
};
} OMAPI2CState;
#define OMAP2_INTR_REV 0x34
#define OMAP2_GC_REV 0x34
static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
static void omap_i2c_interrupts_update(OMAPI2CState *s)
{
qemu_set_irq(s->irq, s->stat & s->mask);
if ((s->dma >> 15) & 1) /* RDMA_EN */
@ -54,7 +60,7 @@ static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */
}
static void omap_i2c_fifo_run(struct omap_i2c_s *s)
static void omap_i2c_fifo_run(OMAPI2CState *s)
{
int ack = 1;
@ -122,8 +128,10 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s)
s->control &= ~(1 << 1); /* STP */
}
void omap_i2c_reset(struct omap_i2c_s *s)
static void omap_i2c_reset(DeviceState *dev)
{
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState,
sysbus_from_qdev(dev));
s->mask = 0;
s->stat = 0;
s->dma = 0;
@ -143,7 +151,7 @@ void omap_i2c_reset(struct omap_i2c_s *s)
static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
{
struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
OMAPI2CState *s = opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
uint16_t ret;
@ -243,7 +251,7 @@ static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
OMAPI2CState *s = opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
int nack;
@ -309,14 +317,14 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
}
if (value & 2)
omap_i2c_reset(s);
omap_i2c_reset(&s->busdev.qdev);
break;
case 0x24: /* I2C_CON */
s->control = value & 0xcf87;
if (~value & (1 << 15)) { /* I2C_EN */
if (s->revision < OMAP2_INTR_REV)
omap_i2c_reset(s);
omap_i2c_reset(&s->busdev.qdev);
break;
}
if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
@ -385,7 +393,7 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
OMAPI2CState *s = opaque;
int offset = addr & OMAP_MPUI_REG_MASK;
switch (offset) {
@ -426,50 +434,59 @@ static const MemoryRegionOps omap_i2c_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
struct omap_i2c_s *omap_i2c_init(MemoryRegion *sysmem,
target_phys_addr_t base,
qemu_irq irq,
qemu_irq *dma,
omap_clk clk)
static int omap_i2c_init(SysBusDevice *dev)
{
struct omap_i2c_s *s = (struct omap_i2c_s *)
g_malloc0(sizeof(struct omap_i2c_s));
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, dev);
/* TODO: set a value greater or equal to real hardware */
s->revision = 0x11;
s->irq = irq;
s->drq[0] = dma[0];
s->drq[1] = dma[1];
s->bus = i2c_init_bus(NULL, "i2c");
omap_i2c_reset(s);
memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c", 0x800);
memory_region_add_subregion(sysmem, base, &s->iomem);
return s;
if (!s->fclk) {
hw_error("omap_i2c: fclk not connected\n");
}
if (s->revision >= OMAP2_INTR_REV && !s->iclk) {
/* Note that OMAP1 doesn't have a separate interface clock */
hw_error("omap_i2c: iclk not connected\n");
}
sysbus_init_irq(dev, &s->irq);
sysbus_init_irq(dev, &s->drq[0]);
sysbus_init_irq(dev, &s->drq[1]);
memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap.i2c",
(s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000);
sysbus_init_mmio(dev, &s->iomem);
s->bus = i2c_init_bus(&dev->qdev, NULL);
return 0;
}
struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
static Property omap_i2c_properties[] = {
DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0),
DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk),
DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk),
DEFINE_PROP_END_OF_LIST(),
};
static void omap_i2c_class_init(ObjectClass *klass, void *data)
{
struct omap_i2c_s *s = (struct omap_i2c_s *)
g_malloc0(sizeof(struct omap_i2c_s));
s->revision = 0x34;
s->irq = irq;
s->drq[0] = dma[0];
s->drq[1] = dma[1];
s->bus = i2c_init_bus(NULL, "i2c");
omap_i2c_reset(s);
memory_region_init_io(&s->iomem, &omap_i2c_ops, s, "omap2.i2c",
omap_l4_region_size(ta, 0));
omap_l4_attach(ta, 0, &s->iomem);
return s;
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = omap_i2c_init;
dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset;
}
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
static TypeInfo omap_i2c_info = {
.name = "omap_i2c",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OMAPI2CState),
.class_init = omap_i2c_class_init,
};
static void omap_i2c_register_types(void)
{
type_register_static(&omap_i2c_info);
}
i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
{
OMAPI2CState *s = FROM_SYSBUS(OMAPI2CState, sysbus_from_qdev(omap_i2c));
return s->bus;
}
type_init(omap_i2c_register_types)

View File

@ -713,7 +713,7 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
addr -= 0x1100;
addr -= 0x10;
addr &= 0xFFFF;
idx = (addr & 0xFFF0) >> 6;
addr = addr & 0x30;
@ -746,7 +746,7 @@ static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
addr -= 0x1100;
addr -= 0x10;
addr &= 0xFFFF;
idx = (addr & 0xFFF0) >> 6;
addr = addr & 0x30;
@ -1361,7 +1361,6 @@ static void mpic_src_ext_write (void *opaque, target_phys_addr_t addr,
if (addr & 0xF)
return;
addr -= MPIC_EXT_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_EXT_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1385,7 +1384,6 @@ static uint32_t mpic_src_ext_read (void *opaque, target_phys_addr_t addr)
if (addr & 0xF)
return retval;
addr -= MPIC_EXT_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_EXT_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1411,7 +1409,6 @@ static void mpic_src_int_write (void *opaque, target_phys_addr_t addr,
if (addr & 0xF)
return;
addr -= MPIC_INT_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_INT_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1435,7 +1432,6 @@ static uint32_t mpic_src_int_read (void *opaque, target_phys_addr_t addr)
if (addr & 0xF)
return retval;
addr -= MPIC_INT_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_INT_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1461,7 +1457,6 @@ static void mpic_src_msg_write (void *opaque, target_phys_addr_t addr,
if (addr & 0xF)
return;
addr -= MPIC_MSG_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_MSG_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1485,7 +1480,6 @@ static uint32_t mpic_src_msg_read (void *opaque, target_phys_addr_t addr)
if (addr & 0xF)
return retval;
addr -= MPIC_MSG_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_MSG_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1511,7 +1505,6 @@ static void mpic_src_msi_write (void *opaque, target_phys_addr_t addr,
if (addr & 0xF)
return;
addr -= MPIC_MSI_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_MSI_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {
@ -1534,7 +1527,6 @@ static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr)
if (addr & 0xF)
return retval;
addr -= MPIC_MSI_REG_START & (OPENPIC_PAGE_SIZE - 1);
if (addr < MPIC_MSI_REG_SIZE) {
idx += (addr & 0xFFF0) >> 5;
if (addr & 0x10) {

View File

@ -2471,6 +2471,8 @@ CPUPPCState *ppc405ep_init(MemoryRegion *address_space_mem,
ppc4xx_pob_init(env);
/* OBP arbitrer */
ppc4xx_opba_init(0xef600600);
/* Initialize timers */
ppc_booke_timers_init(env, sysclk, 0);
/* Universal interrupt controller */
irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
irqs[PPCUIC_OUTPUT_INT] =

View File

@ -182,7 +182,7 @@ static uint64_t spin_read(void *opaque, target_phys_addr_t addr, unsigned len)
}
}
const MemoryRegionOps spin_rw_ops = {
static const MemoryRegionOps spin_rw_ops = {
.read = spin_read,
.write = spin_write,
.endianness = DEVICE_BIG_ENDIAN,

View File

@ -1507,8 +1507,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
i2c_dev = sysbus_from_qdev(qdev_create(NULL, "pxa2xx_i2c"));
qdev_prop_set_uint32(&i2c_dev->qdev, "size", region_size + 1);
qdev_prop_set_uint32(&i2c_dev->qdev, "offset",
base - (base & (~region_size) & TARGET_PAGE_MASK));
qdev_prop_set_uint32(&i2c_dev->qdev, "offset", base & region_size);
qdev_init_nofail(&i2c_dev->qdev);

View File

@ -18,9 +18,9 @@
#define PXA2XX_DMA_NUM_REQUESTS 75
typedef struct {
target_phys_addr_t descr;
target_phys_addr_t src;
target_phys_addr_t dest;
uint32_t descr;
uint32_t src;
uint32_t dest;
uint32_t cmd;
uint32_t state;
int request;
@ -512,9 +512,9 @@ static VMStateDescription vmstate_pxa2xx_dma_chan = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINTTL(descr, PXA2xxDMAChannel),
VMSTATE_UINTTL(src, PXA2xxDMAChannel),
VMSTATE_UINTTL(dest, PXA2xxDMAChannel),
VMSTATE_UINT32(descr, PXA2xxDMAChannel),
VMSTATE_UINT32(src, PXA2xxDMAChannel),
VMSTATE_UINT32(dest, PXA2xxDMAChannel),
VMSTATE_UINT32(cmd, PXA2xxDMAChannel),
VMSTATE_UINT32(state, PXA2xxDMAChannel),
VMSTATE_INT32(request, PXA2xxDMAChannel),

View File

@ -19,15 +19,15 @@
#include "framebuffer.h"
struct DMAChannel {
target_phys_addr_t branch;
uint32_t branch;
uint8_t up;
uint8_t palette[1024];
uint8_t pbuffer[1024];
void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
int *miny, int *maxy);
target_phys_addr_t descriptor;
target_phys_addr_t source;
uint32_t descriptor;
uint32_t source;
uint32_t id;
uint32_t command;
};
@ -929,11 +929,11 @@ static const VMStateDescription vmstate_dma_channel = {
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINTTL(branch, struct DMAChannel),
VMSTATE_UINT32(branch, struct DMAChannel),
VMSTATE_UINT8(up, struct DMAChannel),
VMSTATE_BUFFER(pbuffer, struct DMAChannel),
VMSTATE_UINTTL(descriptor, struct DMAChannel),
VMSTATE_UINTTL(source, struct DMAChannel),
VMSTATE_UINT32(descriptor, struct DMAChannel),
VMSTATE_UINT32(source, struct DMAChannel),
VMSTATE_UINT32(id, struct DMAChannel),
VMSTATE_UINT32(command, struct DMAChannel),
VMSTATE_END_OF_LIST()

View File

@ -83,7 +83,8 @@
sPAPREnvironment *spapr;
qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num)
qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num,
enum xics_irq_type type)
{
uint32_t irq;
qemu_irq qirq;
@ -95,7 +96,7 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num)
irq = spapr->next_irq++;
}
qirq = xics_find_qirq(spapr->icp, irq);
qirq = xics_assign_irq(spapr->icp, irq, type);
if (!qirq) {
return NULL;
}

View File

@ -286,7 +286,18 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode,
target_ulong *args);
qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num);
qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num,
enum xics_irq_type type);
static inline qemu_irq spapr_allocate_msi(uint32_t hint, uint32_t *irq_num)
{
return spapr_allocate_irq(hint, irq_num, XICS_MSI);
}
static inline qemu_irq spapr_allocate_lsi(uint32_t hint, uint32_t *irq_num)
{
return spapr_allocate_irq(hint, irq_num, XICS_LSI);
}
static inline uint32_t rtas_ld(target_ulong phys, int n)
{

View File

@ -32,13 +32,6 @@
#include "hw/pci_internals.h"
static const uint32_t bars[] = {
PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1,
PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3,
PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5
/*, PCI_ROM_ADDRESS*/
};
static PCIDevice *find_dev(sPAPREnvironment *spapr,
uint64_t buid, uint32_t config_addr)
{
@ -187,69 +180,6 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(phb->lsi_table[irq_num].qirq, level);
}
static int spapr_phb_init(SysBusDevice *s)
{
sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s);
int i;
/* Initialize the LSI table */
for (i = 0; i < SPAPR_PCI_NUM_LSI; i++) {
qemu_irq qirq;
uint32_t num;
qirq = spapr_allocate_irq(0, &num);
if (!qirq) {
return -1;
}
phb->lsi_table[i].dt_irq = num;
phb->lsi_table[i].qirq = qirq;
}
return 0;
}
static int spapr_main_pci_host_init(PCIDevice *d)
{
return 0;
}
static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->init = spapr_main_pci_host_init;
}
static TypeInfo spapr_main_pci_host_info = {
.name = "spapr-pci-host-bridge-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
.class_init = spapr_main_pci_host_class_init,
};
static void spapr_phb_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
sdc->init = spapr_phb_init;
}
static TypeInfo spapr_phb_info = {
.name = "spapr-pci-host-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_class_init,
};
static void spapr_register_types(void)
{
type_register_static(&spapr_phb_info);
type_register_static(&spapr_main_pci_host_info);
}
type_init(spapr_register_types)
static uint64_t spapr_io_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
@ -287,35 +217,29 @@ static const MemoryRegionOps spapr_io_ops = {
.write = spapr_io_write
};
void spapr_create_phb(sPAPREnvironment *spapr,
const char *busname, uint64_t buid,
uint64_t mem_win_addr, uint64_t mem_win_size,
uint64_t io_win_addr)
/*
* PHB PCI device
*/
static int spapr_phb_init(SysBusDevice *s)
{
DeviceState *dev;
SysBusDevice *s;
sPAPRPHBState *phb;
sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s);
char *namebuf;
int i;
PCIBus *bus;
char namebuf[strlen(busname)+11];
dev = qdev_create(NULL, "spapr-pci-host-bridge");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
phb = FROM_SYSBUS(sPAPRPHBState, s);
phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid);
namebuf = alloca(strlen(phb->dtbusname) + 32);
phb->mem_win_addr = mem_win_addr;
sprintf(namebuf, "%s-mem", busname);
/* Initialize memory regions */
sprintf(namebuf, "%s.mmio", phb->dtbusname);
memory_region_init(&phb->memspace, namebuf, INT64_MAX);
sprintf(namebuf, "%s-memwindow", busname);
sprintf(namebuf, "%s.mmio-alias", phb->dtbusname);
memory_region_init_alias(&phb->memwindow, namebuf, &phb->memspace,
SPAPR_PCI_MEM_WIN_BUS_OFFSET, mem_win_size);
memory_region_add_subregion(get_system_memory(), mem_win_addr,
SPAPR_PCI_MEM_WIN_BUS_OFFSET, phb->mem_win_size);
memory_region_add_subregion(get_system_memory(), phb->mem_win_addr,
&phb->memwindow);
phb->io_win_addr = io_win_addr;
/* On ppc, we only have MMIO no specific IO space from the CPU
* perspective. In theory we ought to be able to embed the PCI IO
* memory region direction in the system memory space. However,
@ -324,33 +248,92 @@ void spapr_create_phb(sPAPREnvironment *spapr,
* system io address space. This hack to bounce things via
* system_io works around the problem until all the users of
* old_portion are updated */
sprintf(namebuf, "%s-io", busname);
sprintf(namebuf, "%s.io", phb->dtbusname);
memory_region_init(&phb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
/* FIXME: fix to support multiple PHBs */
memory_region_add_subregion(get_system_io(), 0, &phb->iospace);
sprintf(namebuf, "%s-iowindow", busname);
sprintf(namebuf, "%s.io-alias", phb->dtbusname);
memory_region_init_io(&phb->iowindow, &spapr_io_ops, phb,
namebuf, SPAPR_PCI_IO_WIN_SIZE);
memory_region_add_subregion(get_system_memory(), io_win_addr,
memory_region_add_subregion(get_system_memory(), phb->io_win_addr,
&phb->iowindow);
phb->host_state.bus = bus = pci_register_bus(&phb->busdev.qdev, busname,
pci_spapr_set_irq,
pci_spapr_map_irq,
phb,
&phb->memspace, &phb->iospace,
PCI_DEVFN(0, 0),
SPAPR_PCI_NUM_LSI);
bus = pci_register_bus(&phb->busdev.qdev,
phb->busname ? phb->busname : phb->dtbusname,
pci_spapr_set_irq, pci_spapr_map_irq, phb,
&phb->memspace, &phb->iospace,
PCI_DEVFN(0, 0), SPAPR_PCI_NUM_LSI);
phb->host_state.bus = bus;
QLIST_INSERT_HEAD(&spapr->phbs, phb, list);
/* Initialize the LSI table */
for (i = 0; i < SPAPR_PCI_NUM_LSI; i++) {
qemu_irq qirq;
uint32_t num;
qirq = spapr_allocate_lsi(0, &num);
if (!qirq) {
return -1;
}
phb->lsi_table[i].dt_irq = num;
phb->lsi_table[i].qirq = qirq;
}
return 0;
}
static Property spapr_phb_properties[] = {
DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, 0),
DEFINE_PROP_STRING("busname", sPAPRPHBState, busname),
DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, 0),
DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size, 0x20000000),
DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, 0),
DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size, 0x10000),
DEFINE_PROP_END_OF_LIST(),
};
static void spapr_phb_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
sdc->init = spapr_phb_init;
dc->props = spapr_phb_properties;
spapr_rtas_register("read-pci-config", rtas_read_pci_config);
spapr_rtas_register("write-pci-config", rtas_write_pci_config);
spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config);
spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config);
}
QLIST_INSERT_HEAD(&spapr->phbs, phb, list);
static TypeInfo spapr_phb_info = {
.name = "spapr-pci-host-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_class_init,
};
/* pci_bus_set_mem_base(bus, mem_va_start - SPAPR_PCI_MEM_BAR_START); */
void spapr_create_phb(sPAPREnvironment *spapr,
const char *busname, uint64_t buid,
uint64_t mem_win_addr, uint64_t mem_win_size,
uint64_t io_win_addr)
{
DeviceState *dev;
dev = qdev_create(NULL, spapr_phb_info.name);
if (busname) {
qdev_prop_set_string(dev, "busname", g_strdup(busname));
}
qdev_prop_set_uint64(dev, "buid", buid);
qdev_prop_set_uint64(dev, "mem_win_addr", mem_win_addr);
qdev_prop_set_uint64(dev, "mem_win_size", mem_win_size);
qdev_prop_set_uint64(dev, "io_win_addr", io_win_addr);
qdev_init_nofail(dev);
}
/* Macros to operate with address in OF binding to PCI */
@ -442,3 +425,9 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb,
return 0;
}
static void register_types(void)
{
type_register_static(&spapr_phb_info);
}
type_init(register_types)

View File

@ -33,9 +33,11 @@ typedef struct sPAPRPHBState {
PCIHostState host_state;
uint64_t buid;
char *busname;
char *dtbusname;
MemoryRegion memspace, iospace;
target_phys_addr_t mem_win_addr, io_win_addr;
target_phys_addr_t mem_win_addr, mem_win_size, io_win_addr, io_win_size;
MemoryRegion memwindow, iowindow;
struct {

View File

@ -670,7 +670,7 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
dev->qdev.id = id;
}
dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num);
dev->qirq = spapr_allocate_msi(dev->vio_irq_num, &dev->vio_irq_num);
if (!dev->qirq) {
return -1;
}

View File

@ -81,7 +81,7 @@
#define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_SPARC64_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define MAX_PILS 16
#define IVEC_MAX 0x30
#define TICK_MAX 0x7fffffffffffffffULL
@ -304,18 +304,24 @@ static void cpu_kick_irq(CPUSPARCState *env)
qemu_cpu_kick(env);
}
static void cpu_set_irq(void *opaque, int irq, int level)
static void cpu_set_ivec_irq(void *opaque, int irq, int level)
{
CPUSPARCState *env = opaque;
if (level) {
CPUIRQ_DPRINTF("Raise CPU IRQ %d\n", irq);
env->pil_in |= 1 << irq;
cpu_kick_irq(env);
} else {
CPUIRQ_DPRINTF("Lower CPU IRQ %d\n", irq);
env->pil_in &= ~(1 << irq);
cpu_check_irqs(env);
CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
env->interrupt_index = TT_IVEC;
env->pil_in |= 1 << 5;
env->ivec_status |= 0x20;
env->ivec_data[0] = (0x1f << 6) | irq;
env->ivec_data[1] = 0;
env->ivec_data[2] = 0;
cpu_interrupt(env, CPU_INTERRUPT_HARD);
} else {
CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
env->pil_in &= ~(1 << 5);
env->ivec_status &= ~0x20;
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
}
@ -521,13 +527,29 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
}
}
static void dummy_isa_irq_handler(void *opaque, int n, int level)
static void isa_irq_handler(void *opaque, int n, int level)
{
static const int isa_irq_to_ivec[16] = {
[1] = 0x29, /* keyboard */
[4] = 0x2b, /* serial */
[6] = 0x27, /* floppy */
[7] = 0x22, /* parallel */
[12] = 0x2a, /* mouse */
};
qemu_irq *irqs = opaque;
int ivec;
assert(n < 16);
ivec = isa_irq_to_ivec[n];
EBUS_DPRINTF("Set ISA IRQ %d level %d -> ivec 0x%x\n", n, level, ivec);
if (ivec) {
qemu_set_irq(irqs[ivec], level);
}
}
/* EBUS (Eight bit bus) bridge */
static ISABus *
pci_ebus_init(PCIBus *bus, int devfn)
pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs)
{
qemu_irq *isa_irq;
PCIDevice *pci_dev;
@ -536,7 +558,7 @@ pci_ebus_init(PCIBus *bus, int devfn)
pci_dev = pci_create_simple(bus, devfn, "ebus");
isa_bus = DO_UPCAST(ISABus, qbus,
qdev_get_child_bus(&pci_dev->qdev, "isa.0"));
isa_irq = qemu_allocate_irqs(dummy_isa_irq_handler, NULL, 16);
isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16);
isa_bus_irqs(isa_bus, isa_irq);
return isa_bus;
}
@ -761,7 +783,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
long initrd_size, kernel_size;
PCIBus *pci_bus, *pci_bus2, *pci_bus3;
ISABus *isa_bus;
qemu_irq *irq;
qemu_irq *ivec_irqs, *pbm_irqs;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
DriveInfo *fd[MAX_FD];
void *fw_cfg;
@ -774,14 +796,13 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
prom_init(hwdef->prom_addr, bios_name);
irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,
&pci_bus3);
ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, env, IVEC_MAX);
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
&pci_bus3, &pbm_irqs);
pci_vga_init(pci_bus);
// XXX Should be pci_bus3
isa_bus = pci_ebus_init(pci_bus, -1);
isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs);
i = 0;
if (hwdef->console_serial_base) {

145
hw/xics.c
View File

@ -132,9 +132,9 @@ static void icp_eoi(struct icp_state *icp, int server, uint32_t xirr)
{
struct icp_server_state *ss = icp->ss + server;
ics_eoi(icp->ics, xirr & XISR_MASK);
/* Send EOI -> ICS */
ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
ics_eoi(icp->ics, xirr & XISR_MASK);
if (!XISR(ss)) {
icp_resend(icp, server);
}
@ -165,8 +165,9 @@ struct ics_irq_state {
int server;
uint8_t priority;
uint8_t saved_priority;
/* int pending:1; */
/* int presented:1; */
enum xics_irq_type type;
int asserted:1;
int sent:1;
int rejected:1;
int masked_pending:1;
};
@ -185,9 +186,32 @@ static int ics_valid_irq(struct ics_state *ics, uint32_t nr)
&& (nr < (ics->offset + ics->nr_irqs));
}
static void ics_set_irq_msi(void *opaque, int srcno, int val)
static void resend_msi(struct ics_state *ics, int srcno)
{
struct ics_irq_state *irq = ics->irqs + srcno;
/* FIXME: filter by server#? */
if (irq->rejected) {
irq->rejected = 0;
if (irq->priority != 0xff) {
icp_irq(ics->icp, irq->server, srcno + ics->offset,
irq->priority);
}
}
}
static void resend_lsi(struct ics_state *ics, int srcno)
{
struct ics_irq_state *irq = ics->irqs + srcno;
if ((irq->priority != 0xff) && irq->asserted && !irq->sent) {
irq->sent = 1;
icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
}
}
static void set_irq_msi(struct ics_state *ics, int srcno, int val)
{
struct ics_state *ics = (struct ics_state *)opaque;
struct ics_irq_state *irq = ics->irqs + srcno;
if (val) {
@ -200,14 +224,68 @@ static void ics_set_irq_msi(void *opaque, int srcno, int val)
}
}
static void ics_reject_msi(struct ics_state *ics, int nr)
static void set_irq_lsi(struct ics_state *ics, int srcno, int val)
{
struct ics_irq_state *irq = ics->irqs + srcno;
irq->asserted = val;
resend_lsi(ics, srcno);
}
static void ics_set_irq(void *opaque, int srcno, int val)
{
struct ics_state *ics = (struct ics_state *)opaque;
struct ics_irq_state *irq = ics->irqs + srcno;
if (irq->type == XICS_LSI) {
set_irq_lsi(ics, srcno, val);
} else {
set_irq_msi(ics, srcno, val);
}
}
static void write_xive_msi(struct ics_state *ics, int srcno)
{
struct ics_irq_state *irq = ics->irqs + srcno;
if (!irq->masked_pending || (irq->priority == 0xff)) {
return;
}
irq->masked_pending = 0;
icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
}
static void write_xive_lsi(struct ics_state *ics, int srcno)
{
resend_lsi(ics, srcno);
}
static void ics_write_xive(struct ics_state *ics, int nr, int server,
uint8_t priority)
{
int srcno = nr - ics->offset;
struct ics_irq_state *irq = ics->irqs + srcno;
irq->server = server;
irq->priority = priority;
if (irq->type == XICS_LSI) {
write_xive_lsi(ics, srcno);
} else {
write_xive_msi(ics, srcno);
}
}
static void ics_reject(struct ics_state *ics, int nr)
{
struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
irq->rejected = 1;
irq->rejected = 1; /* Irrelevant but harmless for LSI */
irq->sent = 0; /* Irrelevant but harmless for MSI */
}
static void ics_resend_msi(struct ics_state *ics)
static void ics_resend(struct ics_state *ics)
{
int i;
@ -215,56 +293,39 @@ static void ics_resend_msi(struct ics_state *ics)
struct ics_irq_state *irq = ics->irqs + i;
/* FIXME: filter by server#? */
if (irq->rejected) {
irq->rejected = 0;
if (irq->priority != 0xff) {
icp_irq(ics->icp, irq->server, i + ics->offset, irq->priority);
}
if (irq->type == XICS_LSI) {
resend_lsi(ics, i);
} else {
resend_msi(ics, i);
}
}
}
static void ics_write_xive_msi(struct ics_state *ics, int nr, int server,
uint8_t priority)
{
struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
irq->server = server;
irq->priority = priority;
if (!irq->masked_pending || (priority == 0xff)) {
return;
}
irq->masked_pending = 0;
icp_irq(ics->icp, server, nr, priority);
}
static void ics_reject(struct ics_state *ics, int nr)
{
ics_reject_msi(ics, nr);
}
static void ics_resend(struct ics_state *ics)
{
ics_resend_msi(ics);
}
static void ics_eoi(struct ics_state *ics, int nr)
{
int srcno = nr - ics->offset;
struct ics_irq_state *irq = ics->irqs + srcno;
if (irq->type == XICS_LSI) {
irq->sent = 0;
}
}
/*
* Exported functions
*/
qemu_irq xics_find_qirq(struct icp_state *icp, int irq)
qemu_irq xics_assign_irq(struct icp_state *icp, int irq,
enum xics_irq_type type)
{
if ((irq < icp->ics->offset)
|| (irq >= (icp->ics->offset + icp->ics->nr_irqs))) {
return NULL;
}
assert((type == XICS_MSI) || (type == XICS_LSI));
icp->ics->irqs[irq - icp->ics->offset].type = type;
return icp->ics->qirqs[irq - icp->ics->offset];
}
@ -332,7 +393,7 @@ static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
return;
}
ics_write_xive_msi(ics, nr, server, priority);
ics_write_xive(ics, nr, server, priority);
rtas_st(rets, 0, 0); /* Success */
}
@ -477,7 +538,7 @@ struct icp_state *xics_system_init(int nr_irqs)
ics->irqs[i].saved_priority = 0xff;
}
ics->qirqs = qemu_allocate_irqs(ics_set_irq_msi, ics, nr_irqs);
ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs);
spapr_register_hypercall(H_CPPR, h_cppr);
spapr_register_hypercall(H_IPI, h_ipi);

View File

@ -31,7 +31,13 @@
struct icp_state;
qemu_irq xics_find_qirq(struct icp_state *icp, int irq);
enum xics_irq_type {
XICS_MSI, /* Message-signalled (edge) interrupt */
XICS_LSI, /* Level-signalled interrupt */
};
qemu_irq xics_assign_irq(struct icp_state *icp, int irq,
enum xics_irq_type type);
struct icp_state *xics_system_init(int nr_irqs);

View File

@ -79,7 +79,10 @@ struct KVMState
int pit_state2;
int xsave, xcrs;
int many_ioeventfds;
int irqchip_inject_ioctl;
/* The man page (and posix) say ioctl numbers are signed int, but
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
* unsigned, and treating them as signed here can break things */
unsigned irqchip_inject_ioctl;
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing *irq_routes;
int nr_allocated_irq_routes;

View File

@ -4118,7 +4118,7 @@ static target_ulong get_sigframe(struct target_sigaction *ka,
oldsp = env->gpr[1];
if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
(sas_ss_flags(oldsp))) {
(sas_ss_flags(oldsp) == 0)) {
oldsp = (target_sigaltstack_used.ss_sp
+ target_sigaltstack_used.ss_size);
}

View File

@ -70,12 +70,6 @@
#define inline always_inline
#endif
#ifdef __i386__
#define REGPARM __attribute((regparm(3)))
#else
#define REGPARM
#endif
#define qemu_printf printf
int qemu_daemon(int nochdir, int noclose);

View File

@ -17,7 +17,7 @@
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
implementation for certain IBM POWER hardware. The sources are at
https://github.com/dgibson/SLOF, and the image currently in qemu is
built from git tag qemu-slof-20120111.1.
built from git tag qemu-slof-20120217.
- sgabios (the Serial Graphics Adapter option ROM) provides a means for
legacy x86 software to communicate with an attached serial console as

Binary file not shown.

@ -1 +1 @@
Subproject commit ab062ff3b37c39649f2b0d94ed607adc6f6b3c7d
Subproject commit d153364253548d6cd91403711f84996e6a7dab31

View File

@ -1486,6 +1486,8 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
n_elems = field->num;
} else if (field->flags & VMS_VARRAY_INT32) {
n_elems = *(int32_t *)(opaque+field->num_offset);
} else if (field->flags & VMS_VARRAY_UINT32) {
n_elems = *(uint32_t *)(opaque+field->num_offset);
} else if (field->flags & VMS_VARRAY_UINT16) {
n_elems = *(uint16_t *)(opaque+field->num_offset);
} else if (field->flags & VMS_VARRAY_UINT8) {

View File

@ -9,22 +9,50 @@
#ifndef SOFTMMU_DEFS_H
#define SOFTMMU_DEFS_H
uint8_t REGPARM __ldb_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t REGPARM __ldw_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t REGPARM __ldl_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_mmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx);
#ifndef CONFIG_TCG_PASS_AREG0
uint8_t __ldb_mmu(target_ulong addr, int mmu_idx);
void __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t __ldw_mmu(target_ulong addr, int mmu_idx);
void __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t __ldl_mmu(target_ulong addr, int mmu_idx);
void __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t __ldq_mmu(target_ulong addr, int mmu_idx);
void __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx);
uint8_t REGPARM __ldb_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t REGPARM __ldw_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx);
void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
uint8_t __ldb_cmmu(target_ulong addr, int mmu_idx);
void __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx);
uint16_t __ldw_cmmu(target_ulong addr, int mmu_idx);
void __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx);
uint32_t __ldl_cmmu(target_ulong addr, int mmu_idx);
void __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
uint64_t __ldq_cmmu(target_ulong addr, int mmu_idx);
void __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
#else
uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
int mmu_idx);
uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
int mmu_idx);
uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
int mmu_idx);
uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
int mmu_idx);
uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stb_cmmu(CPUArchState *env, target_ulong addr, uint8_t val,
int mmu_idx);
uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stw_cmmu(CPUArchState *env, target_ulong addr, uint16_t val,
int mmu_idx);
uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stl_cmmu(CPUArchState *env, target_ulong addr, uint32_t val,
int mmu_idx);
uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
int mmu_idx);
#endif
#endif

View File

@ -78,9 +78,23 @@
#define ADDR_READ addr_read
#endif
#ifndef CONFIG_TCG_PASS_AREG0
#define ENV_PARAM
#define ENV_VAR
#define CPU_PREFIX
#define HELPER_PREFIX __
#else
#define ENV_PARAM CPUArchState *env,
#define ENV_VAR env,
#define CPU_PREFIX cpu_
#define HELPER_PREFIX helper_
#endif
/* generic load/store macros */
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
static inline RES_TYPE
glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
target_ulong ptr)
{
int page_index;
RES_TYPE res;
@ -93,7 +107,9 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_VAR
addr,
mmu_idx);
} else {
physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
@ -102,7 +118,9 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
}
#if DATA_SIZE <= 2
static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
static inline int
glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
target_ulong ptr)
{
int res, page_index;
target_ulong addr;
@ -114,7 +132,8 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
MMUSUFFIX)(ENV_VAR addr, mmu_idx);
} else {
physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
@ -127,7 +146,9 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
/* generic store macro */
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
static inline void
glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
RES_TYPE v)
{
int page_index;
target_ulong addr;
@ -139,7 +160,8 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, v,
mmu_idx);
} else {
physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
@ -151,46 +173,52 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
#if DATA_SIZE == 8
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
static inline float64 glue(glue(CPU_PREFIX, ldfq), MEMSUFFIX)(ENV_PARAM
target_ulong ptr)
{
union {
float64 d;
uint64_t i;
} u;
u.i = glue(ldq, MEMSUFFIX)(ptr);
u.i = glue(glue(CPU_PREFIX, ldq), MEMSUFFIX)(ENV_VAR ptr);
return u.d;
}
static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
static inline void glue(glue(CPU_PREFIX, stfq), MEMSUFFIX)(ENV_PARAM
target_ulong ptr,
float64 v)
{
union {
float64 d;
uint64_t i;
} u;
u.d = v;
glue(stq, MEMSUFFIX)(ptr, u.i);
glue(glue(CPU_PREFIX, stq), MEMSUFFIX)(ENV_VAR ptr, u.i);
}
#endif /* DATA_SIZE == 8 */
#if DATA_SIZE == 4
static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
static inline float32 glue(glue(CPU_PREFIX, ldfl), MEMSUFFIX)(ENV_PARAM
target_ulong ptr)
{
union {
float32 f;
uint32_t i;
} u;
u.i = glue(ldl, MEMSUFFIX)(ptr);
u.i = glue(glue(CPU_PREFIX, ldl), MEMSUFFIX)(ENV_VAR ptr);
return u.f;
}
static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
static inline void glue(glue(CPU_PREFIX, stfl), MEMSUFFIX)(ENV_PARAM
target_ulong ptr,
float32 v)
{
union {
float32 f;
uint32_t i;
} u;
u.f = v;
glue(stl, MEMSUFFIX)(ptr, u.i);
glue(glue(CPU_PREFIX, stl), MEMSUFFIX)(ENV_VAR ptr, u.i);
}
#endif /* DATA_SIZE == 4 */
@ -205,3 +233,7 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
#undef CPU_MMU_INDEX
#undef MMUSUFFIX
#undef ADDR_READ
#undef ENV_PARAM
#undef ENV_VAR
#undef CPU_PREFIX
#undef HELPER_PREFIX

View File

@ -54,10 +54,24 @@
#define ADDR_READ addr_read
#endif
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
#ifndef CONFIG_TCG_PASS_AREG0
#define ENV_PARAM
#define ENV_VAR
#define CPU_PREFIX
#define HELPER_PREFIX __
#else
#define ENV_PARAM CPUArchState *env,
#define ENV_VAR env,
#define CPU_PREFIX cpu_
#define HELPER_PREFIX helper_
#endif
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
int mmu_idx,
void *retaddr);
static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
target_phys_addr_t physaddr,
target_ulong addr,
void *retaddr)
{
@ -89,8 +103,10 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
}
/* handle all cases except unaligned access which span two pages */
DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int mmu_idx)
DATA_TYPE
glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
int mmu_idx)
{
DATA_TYPE res;
int index;
@ -111,22 +127,22 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
goto do_unaligned_access;
retaddr = GETPC();
ioaddr = env->iotlb[mmu_idx][index];
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
/* slow unaligned access (it spans two pages or IO) */
do_unaligned_access:
retaddr = GETPC();
#ifdef ALIGNED_ONLY
do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
#endif
res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr,
mmu_idx, retaddr);
} else {
/* unaligned/aligned access in the same page */
#ifdef ALIGNED_ONLY
if ((addr & (DATA_SIZE - 1)) != 0) {
retaddr = GETPC();
do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
}
#endif
addend = env->tlb_table[mmu_idx][index].addend;
@ -137,7 +153,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
retaddr = GETPC();
#ifdef ALIGNED_ONLY
if ((addr & (DATA_SIZE - 1)) != 0)
do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
#endif
tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
goto redo;
@ -146,9 +162,11 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
}
/* handle all unaligned cases */
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int mmu_idx,
void *retaddr)
static DATA_TYPE
glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
int mmu_idx,
void *retaddr)
{
DATA_TYPE res, res1, res2;
int index, shift;
@ -165,15 +183,15 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
ioaddr = env->iotlb[mmu_idx][index];
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* slow unaligned access (it spans two pages) */
addr1 = addr & ~(DATA_SIZE - 1);
addr2 = addr1 + DATA_SIZE;
res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr1,
mmu_idx, retaddr);
res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr2,
mmu_idx, retaddr);
shift = (addr & (DATA_SIZE - 1)) * 8;
#ifdef TARGET_WORDS_BIGENDIAN
@ -197,12 +215,14 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
#ifndef SOFTMMU_CODE_ACCESS
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
DATA_TYPE val,
int mmu_idx,
void *retaddr);
static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
static inline void glue(io_write, SUFFIX)(ENV_PARAM
target_phys_addr_t physaddr,
DATA_TYPE val,
target_ulong addr,
void *retaddr)
@ -232,9 +252,10 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
#endif /* SHIFT > 2 */
}
void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int mmu_idx)
void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
DATA_TYPE val,
int mmu_idx)
{
target_phys_addr_t ioaddr;
unsigned long addend;
@ -252,21 +273,21 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
goto do_unaligned_access;
retaddr = GETPC();
ioaddr = env->iotlb[mmu_idx][index];
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
retaddr = GETPC();
#ifdef ALIGNED_ONLY
do_unaligned_access(addr, 1, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
#endif
glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_VAR addr, val,
mmu_idx, retaddr);
} else {
/* aligned/unaligned access in the same page */
#ifdef ALIGNED_ONLY
if ((addr & (DATA_SIZE - 1)) != 0) {
retaddr = GETPC();
do_unaligned_access(addr, 1, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
}
#endif
addend = env->tlb_table[mmu_idx][index].addend;
@ -277,7 +298,7 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
retaddr = GETPC();
#ifdef ALIGNED_ONLY
if ((addr & (DATA_SIZE - 1)) != 0)
do_unaligned_access(addr, 1, mmu_idx, retaddr);
do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
#endif
tlb_fill(env, addr, 1, mmu_idx, retaddr);
goto redo;
@ -285,7 +306,8 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
}
/* handles all unaligned cases */
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
target_ulong addr,
DATA_TYPE val,
int mmu_idx,
void *retaddr)
@ -304,7 +326,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
ioaddr = env->iotlb[mmu_idx][index];
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* XXX: not efficient, but simple */
@ -312,10 +334,12 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
* previous page from the TLB cache. */
for(i = DATA_SIZE - 1; i >= 0; i--) {
#ifdef TARGET_WORDS_BIGENDIAN
glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
mmu_idx, retaddr);
#else
glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
val >> (i * 8),
mmu_idx, retaddr);
#endif
}
@ -340,3 +364,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
#undef USUFFIX
#undef DATA_SIZE
#undef ADDR_READ
#undef ENV_PARAM
#undef ENV_VAR
#undef CPU_PREFIX
#undef HELPER_PREFIX

View File

@ -877,7 +877,8 @@ static void do_interrupt_v7m(CPUARMState *env)
v7m_push(env, env->regs[1]);
v7m_push(env, env->regs[0]);
switch_v7m_sp(env, 0);
env->uncached_cpsr &= ~CPSR_IT;
/* Clear IT bits */
env->condexec_bits = 0;
env->regs[14] = lr;
addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
env->regs[15] = addr & 0xfffffffe;
@ -2025,7 +2026,7 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
return env->cp15.c5_data;
case 1:
if (arm_feature(env, ARM_FEATURE_MPU))
return simple_mpu_ap_bits(env->cp15.c5_data);
return simple_mpu_ap_bits(env->cp15.c5_insn);
return env->cp15.c5_insn;
case 2:
if (!arm_feature(env, ARM_FEATURE_MPU))

View File

@ -9704,32 +9704,49 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
store_reg(s, rd, tmp);
break;
case 6: /* cps */
ARCH(6);
if (IS_USER(s))
case 6:
switch ((insn >> 5) & 7) {
case 2:
/* setend */
ARCH(6);
if (insn & (1 << 3)) {
/* BE8 mode not implemented. */
goto illegal_op;
}
break;
if (IS_M(env)) {
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
/* FAULTMASK */
if (insn & 1) {
addr = tcg_const_i32(19);
gen_helper_v7m_msr(cpu_env, addr, tmp);
tcg_temp_free_i32(addr);
case 3:
/* cps */
ARCH(6);
if (IS_USER(s)) {
break;
}
/* PRIMASK */
if (insn & 2) {
addr = tcg_const_i32(16);
gen_helper_v7m_msr(cpu_env, addr, tmp);
tcg_temp_free_i32(addr);
if (IS_M(env)) {
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
/* FAULTMASK */
if (insn & 1) {
addr = tcg_const_i32(19);
gen_helper_v7m_msr(cpu_env, addr, tmp);
tcg_temp_free_i32(addr);
}
/* PRIMASK */
if (insn & 2) {
addr = tcg_const_i32(16);
gen_helper_v7m_msr(cpu_env, addr, tmp);
tcg_temp_free_i32(addr);
}
tcg_temp_free_i32(tmp);
gen_lookup_tb(s);
} else {
if (insn & (1 << 4)) {
shift = CPSR_A | CPSR_I | CPSR_F;
} else {
shift = 0;
}
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
}
tcg_temp_free_i32(tmp);
gen_lookup_tb(s);
} else {
if (insn & (1 << 4))
shift = CPSR_A | CPSR_I | CPSR_F;
else
shift = 0;
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
break;
default:
goto undef;
}
break;

View File

@ -1918,8 +1918,10 @@ enum {
PPC2_DFP = 0x0000000000000004ULL,
/* Embedded.Processor Control */
PPC2_PRCNTL = 0x0000000000000008ULL,
/* Byte-reversed, indexed, double-word load and store */
PPC2_DBRX = 0x0000000000000010ULL,
#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL)
#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_DBRX)
};
/*****************************************************************************/

View File

@ -591,12 +591,6 @@ static inline int _find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h,
pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
}
/* We have a TLB that saves 4K pages, so let's
* split a huge page to 4k chunks */
if (target_page_bits != TARGET_PAGE_BITS)
pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
& TARGET_PAGE_MASK;
r = pte64_check(ctx, pte0, pte1, h, rw, type);
LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
@ -672,6 +666,12 @@ static inline int _find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h,
}
}
/* We have a TLB that saves 4K pages, so let's
* split a huge page to 4k chunks */
if (target_page_bits != TARGET_PAGE_BITS) {
ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1))
& TARGET_PAGE_MASK;
}
return ret;
}

View File

@ -843,12 +843,18 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
int fd;
void *table;
/* Must set fd to -1 so we don't try to munmap when called for
* destroying the table, which the upper layers -will- do
*/
*pfd = -1;
if (!cap_spapr_tce) {
return NULL;
}
fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
if (fd < 0) {
fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
liobn);
return NULL;
}
@ -857,6 +863,8 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (table == MAP_FAILED) {
fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n",
liobn);
close(fd);
return NULL;
}
@ -876,8 +884,8 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE);
if ((munmap(table, len) < 0) ||
(close(fd) < 0)) {
fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE "
"table: %s", strerror(errno));
fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
strerror(errno));
/* Leak the table */
}

View File

@ -2650,7 +2650,7 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
tcg_temp_free(EA); \
}
#define GEN_LDX(name, ldop, opc2, opc3, type) \
#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \
static void glue(gen_, name##x)(DisasContext *ctx) \
{ \
TCGv EA; \
@ -2660,6 +2660,8 @@ static void glue(gen_, name##x)(DisasContext *ctx) \
gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
#define GEN_LDX(name, ldop, opc2, opc3, type) \
GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
#define GEN_LDS(name, ldop, op, type) \
GEN_LD(name, ldop, op | 0x20, type); \
@ -2793,8 +2795,8 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
tcg_temp_free(EA); \
}
#define GEN_STX(name, stop, opc2, opc3, type) \
static void glue(gen_, name##x)(DisasContext *ctx) \
#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \
static void glue(gen_, name##x)(DisasContext *ctx) \
{ \
TCGv EA; \
gen_set_access_type(ctx, ACCESS_INT); \
@ -2803,6 +2805,8 @@ static void glue(gen_, name##x)(DisasContext *ctx)
gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
#define GEN_STX(name, stop, opc2, opc3, type) \
GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
#define GEN_STS(name, stop, op, type) \
GEN_ST(name, stop, op | 0x20, type); \
@ -2891,6 +2895,18 @@ static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
}
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
#if defined(TARGET_PPC64)
/* ldbrx */
static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
if (likely(!ctx->le_mode)) {
tcg_gen_bswap64_tl(arg1, arg1);
}
}
GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
#endif /* TARGET_PPC64 */
/* sthbrx */
static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
@ -2921,6 +2937,22 @@ static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
}
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
#if defined(TARGET_PPC64)
/* stdbrx */
static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
if (likely(!ctx->le_mode)) {
TCGv t0 = tcg_temp_new();
tcg_gen_bswap64_tl(t0, arg1);
tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
tcg_temp_free(t0);
} else {
tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
}
}
GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
#endif /* TARGET_PPC64 */
/*** Integer load and store multiple ***/
/* lmw */
@ -8818,7 +8850,7 @@ GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
#undef GEN_LD
#undef GEN_LDU
#undef GEN_LDUX
#undef GEN_LDX
#undef GEN_LDX_E
#undef GEN_LDS
#define GEN_LD(name, ldop, opc, type) \
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
@ -8826,8 +8858,8 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
#define GEN_LDUX(name, ldop, opc2, opc3, type) \
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
#define GEN_LDX(name, ldop, opc2, opc3, type) \
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \
GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
#define GEN_LDS(name, ldop, op, type) \
GEN_LD(name, ldop, op | 0x20, type) \
GEN_LDU(name, ldop, op | 0x21, type) \
@ -8843,6 +8875,7 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
#endif
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
@ -8850,7 +8883,7 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
#undef GEN_ST
#undef GEN_STU
#undef GEN_STUX
#undef GEN_STX
#undef GEN_STX_E
#undef GEN_STS
#define GEN_ST(name, stop, opc, type) \
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
@ -8858,8 +8891,8 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
#define GEN_STUX(name, stop, opc2, opc3, type) \
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
#define GEN_STX(name, stop, opc2, opc3, type) \
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \
GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
#define GEN_STS(name, stop, op, type) \
GEN_ST(name, stop, op | 0x20, type) \
GEN_STU(name, stop, op | 0x21, type) \
@ -8872,6 +8905,7 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER)
#if defined(TARGET_PPC64)
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
#endif
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
@ -9285,6 +9319,8 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
int i;
cpu_synchronize_state(env);
cpu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR "
TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
env->nip, env->lr, env->ctr, env->xer);

View File

@ -6571,7 +6571,7 @@ static void init_proc_970MP (CPUPPCState *env)
PPC_64B | PPC_ALTIVEC | \
PPC_SEGMENT_64B | PPC_SLBI | \
PPC_POPCNTB | PPC_POPCNTWD)
#define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP)
#define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP | PPC2_DBRX)
#define POWERPC_MSRM_POWER7 (0x800000000204FF36ULL)
#define POWERPC_MMU_POWER7 (POWERPC_MMU_2_06)
#define POWERPC_EXCP_POWER7 (POWERPC_EXCP_POWER7)
@ -6588,6 +6588,11 @@ static void init_proc_POWER7 (CPUPPCState *env)
gen_spr_7xx(env);
/* Time base */
gen_tbl(env);
/* Processor identification */
spr_register(env, SPR_PIR, "PIR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_pir,
0x00000000);
#if !defined(CONFIG_USER_ONLY)
/* PURR & SPURR: Hack - treat these as aliases for the TB for now */
spr_register(env, SPR_PURR, "PURR",
@ -6713,7 +6718,7 @@ static void init_proc_620 (CPUPPCState *env)
#if defined (TARGET_PPC64) && 0 // XXX: TODO
#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC64
#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC64
#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS_PPC64
#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS2_PPC64
#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC64
#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC64
#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC64
@ -6725,7 +6730,7 @@ static void init_proc_620 (CPUPPCState *env)
#else
#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32
#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32
#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS_PPC32
#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS2_PPC32
#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC32
#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC32
#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC32

View File

@ -415,14 +415,15 @@ struct CPUSPARCState {
#if !defined(TARGET_SPARC64)
int psref; /* enable fpu */
#endif
target_ulong version;
int interrupt_index;
uint32_t nwindows;
/* NOTE: we allow 8 more registers to handle wrapping */
target_ulong regbase[MAX_NWINDOWS * 16 + 8];
CPU_COMMON
target_ulong version;
uint32_t nwindows;
/* MMU regs */
#if defined(TARGET_SPARC64)
uint64_t lsu;
@ -492,6 +493,9 @@ struct CPUSPARCState {
/* UA 2005 hyperprivileged registers */
uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
CPUTimer *hstick; // UA 2005
/* Interrupt vector registers */
uint64_t ivec_status;
uint64_t ivec_data[3];
uint32_t softint;
#define SOFTINT_TIMER 1
#define SOFTINT_STIMER (1 << 16)
@ -582,7 +586,6 @@ void cpu_unassigned_access(CPUSPARCState *env1, target_phys_addr_t addr,
#if defined(TARGET_SPARC64)
target_phys_addr_t cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
int mmu_idx);
#endif
#endif
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
@ -696,6 +699,8 @@ uint64_t cpu_tick_get_count(CPUTimer *timer);
void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
trap_state* cpu_tsptr(CPUSPARCState* env);
#endif
void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
int is_user, void *retaddr);
#define TB_FLAG_FPU_ENABLED (1 << 4)
#define TB_FLAG_AM_ENABLED (1 << 5)

View File

@ -30,6 +30,7 @@ void cpu_state_reset(CPUSPARCState *env)
log_cpu_state(env, 0);
}
memset(env, 0, offsetof(CPUSPARCState, breakpoints));
tlb_flush(env, 1);
env->cwp = 0;
#ifndef TARGET_SPARC64

View File

@ -18,11 +18,11 @@ DEF_HELPER_1(rdcwp, tl, env)
DEF_HELPER_2(wrcwp, void, env, tl)
DEF_HELPER_FLAGS_2(array8, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
DEF_HELPER_1(popc, tl, tl)
DEF_HELPER_3(ldda_asi, void, tl, int, int)
DEF_HELPER_4(ldf_asi, void, tl, int, int, int)
DEF_HELPER_4(stf_asi, void, tl, int, int, int)
DEF_HELPER_4(cas_asi, tl, tl, tl, tl, i32)
DEF_HELPER_4(casx_asi, tl, tl, tl, tl, i32)
DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
DEF_HELPER_2(set_softint, void, env, i64)
DEF_HELPER_2(clear_softint, void, env, i64)
DEF_HELPER_2(write_softint, void, env, i64)
@ -30,7 +30,7 @@ DEF_HELPER_2(tick_set_count, void, ptr, i64)
DEF_HELPER_1(tick_get_count, i64, ptr)
DEF_HELPER_2(tick_set_limit, void, ptr, i64)
#endif
DEF_HELPER_2(check_align, void, tl, i32)
DEF_HELPER_3(check_align, void, env, tl, i32)
DEF_HELPER_1(debug, void, env)
DEF_HELPER_1(save, void, env)
DEF_HELPER_1(restore, void, env)
@ -38,11 +38,11 @@ DEF_HELPER_3(udiv, tl, env, tl, tl)
DEF_HELPER_3(udiv_cc, tl, env, tl, tl)
DEF_HELPER_3(sdiv, tl, env, tl, tl)
DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
DEF_HELPER_2(ldqf, void, tl, int)
DEF_HELPER_2(stqf, void, tl, int)
DEF_HELPER_3(ldqf, void, env, tl, int)
DEF_HELPER_3(stqf, void, env, tl, int)
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
DEF_HELPER_4(ld_asi, i64, tl, int, int, int)
DEF_HELPER_4(st_asi, void, tl, i64, int, int)
DEF_HELPER_5(ld_asi, i64, env, tl, int, int, int)
DEF_HELPER_5(st_asi, void, env, tl, i64, int, int)
#endif
DEF_HELPER_2(ldfsr, void, env, i32)
DEF_HELPER_FLAGS_1(fabss, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32)

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
#include "cpu.h"
#include "dyngen-exec.h"
#include "helper.h"
#if !defined(CONFIG_USER_ONLY)
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
void *retaddr);
#define MMUSUFFIX _mmu
#define ALIGNED_ONLY
#define SHIFT 0
#include "softmmu_template.h"
#define SHIFT 1
#include "softmmu_template.h"
#define SHIFT 2
#include "softmmu_template.h"
#define SHIFT 3
#include "softmmu_template.h"
/* XXX: make it generic ? */
static void cpu_restore_state2(void *retaddr)
{
TranslationBlock *tb;
unsigned long pc;
if (retaddr) {
/* now we have a real cpu fault */
pc = (unsigned long)retaddr;
tb = tb_find_pc(pc);
if (tb) {
/* the PC is inside the translated code. It means that we have
a virtual CPU fault */
cpu_restore_state(tb, env, pc);
}
}
}
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
void *retaddr)
{
#ifdef DEBUG_UNALIGNED
printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
"\n", addr, env->pc);
#endif
cpu_restore_state2(retaddr);
helper_raise_exception(env, TT_UNALIGNED);
}
/* try to fill the TLB and return an exception if error. If retaddr is
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
void tlb_fill(CPUSPARCState *env1, target_ulong addr, int is_write, int mmu_idx,
void *retaddr)
{
int ret;
CPUSPARCState *saved_env;
saved_env = env;
env = env1;
ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (ret) {
cpu_restore_state2(retaddr);
cpu_loop_exit(env);
}
env = saved_env;
}
#endif /* !CONFIG_USER_ONLY */

View File

@ -1955,7 +1955,7 @@ static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(size);
r_sign = tcg_const_i32(sign);
gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_size, r_sign);
tcg_temp_free_i32(r_sign);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
@ -1967,7 +1967,7 @@ static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(size);
gen_helper_st_asi(addr, src, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
}
@ -1979,7 +1979,7 @@ static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(size);
r_rd = tcg_const_i32(rd);
gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
gen_helper_ldf_asi(cpu_env, addr, r_asi, r_size, r_rd);
tcg_temp_free_i32(r_rd);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
@ -1992,7 +1992,7 @@ static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(size);
r_rd = tcg_const_i32(rd);
gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
gen_helper_stf_asi(cpu_env, addr, r_asi, r_size, r_rd);
tcg_temp_free_i32(r_rd);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
@ -2005,9 +2005,9 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(4);
r_sign = tcg_const_i32(0);
gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
gen_helper_ld_asi(cpu_tmp64, cpu_env, addr, r_asi, r_size, r_sign);
tcg_temp_free_i32(r_sign);
gen_helper_st_asi(addr, dst, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, dst, r_asi, r_size);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
@ -2019,7 +2019,7 @@ static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
r_asi = gen_get_asi(insn, addr);
r_rd = tcg_const_i32(rd);
gen_helper_ldda_asi(addr, r_asi, r_rd);
gen_helper_ldda_asi(cpu_env, addr, r_asi, r_rd);
tcg_temp_free_i32(r_rd);
tcg_temp_free_i32(r_asi);
}
@ -2032,7 +2032,7 @@ static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
r_asi = gen_get_asi(insn, addr);
r_size = tcg_const_i32(8);
gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, cpu_tmp64, r_asi, r_size);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
}
@ -2046,7 +2046,7 @@ static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
r_val1 = tcg_temp_new();
gen_movl_reg_TN(rd, r_val1);
r_asi = gen_get_asi(insn, addr);
gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
gen_helper_cas_asi(dst, cpu_env, addr, r_val1, val2, r_asi);
tcg_temp_free_i32(r_asi);
tcg_temp_free(r_val1);
}
@ -2058,7 +2058,7 @@ static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
gen_movl_reg_TN(rd, cpu_tmp64);
r_asi = gen_get_asi(insn, addr);
gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
gen_helper_casx_asi(dst, cpu_env, addr, cpu_tmp64, val2, r_asi);
tcg_temp_free_i32(r_asi);
}
@ -2072,7 +2072,7 @@ static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(size);
r_sign = tcg_const_i32(sign);
gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
gen_helper_ld_asi(cpu_tmp64, cpu_env, addr, r_asi, r_size, r_sign);
tcg_temp_free(r_sign);
tcg_temp_free(r_size);
tcg_temp_free(r_asi);
@ -2086,7 +2086,7 @@ static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
tcg_gen_extu_tl_i64(cpu_tmp64, src);
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(size);
gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, cpu_tmp64, r_asi, r_size);
tcg_temp_free(r_size);
tcg_temp_free(r_asi);
}
@ -2099,11 +2099,11 @@ static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(4);
r_sign = tcg_const_i32(0);
gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
gen_helper_ld_asi(cpu_tmp64, cpu_env, addr, r_asi, r_size, r_sign);
tcg_temp_free(r_sign);
r_val = tcg_temp_new_i64();
tcg_gen_extu_tl_i64(r_val, dst);
gen_helper_st_asi(addr, r_val, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, r_val, r_asi, r_size);
tcg_temp_free_i64(r_val);
tcg_temp_free(r_size);
tcg_temp_free(r_asi);
@ -2117,7 +2117,7 @@ static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(8);
r_sign = tcg_const_i32(0);
gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
gen_helper_ld_asi(cpu_tmp64, cpu_env, addr, r_asi, r_size, r_sign);
tcg_temp_free(r_sign);
tcg_temp_free(r_size);
tcg_temp_free(r_asi);
@ -2136,7 +2136,7 @@ static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(8);
gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, cpu_tmp64, r_asi, r_size);
tcg_temp_free(r_size);
tcg_temp_free(r_asi);
}
@ -2153,7 +2153,7 @@ static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
r_val = tcg_const_i64(0xffULL);
r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
r_size = tcg_const_i32(1);
gen_helper_st_asi(addr, r_val, r_asi, r_size);
gen_helper_st_asi(cpu_env, addr, r_val, r_asi, r_size);
tcg_temp_free_i32(r_size);
tcg_temp_free_i32(r_asi);
tcg_temp_free_i64(r_val);
@ -2373,9 +2373,9 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
goto nfpu_insn;
/* before an instruction, dc->pc must be static */
static void disas_sparc_insn(DisasContext * dc)
static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
unsigned int insn, opc, rs1, rs2, rd;
unsigned int opc, rs1, rs2, rd;
TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2;
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
@ -2383,7 +2383,7 @@ static void disas_sparc_insn(DisasContext * dc)
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
tcg_gen_debug_insn_start(dc->pc);
insn = ldl_code(dc->pc);
opc = GET_FIELD(insn, 0, 1);
rd = GET_FIELD(insn, 2, 6);
@ -4547,7 +4547,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_helper_restore(cpu_env);
gen_mov_pc_npc(dc, cpu_cond);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_dst, r_const);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
tcg_gen_mov_tl(cpu_npc, cpu_dst);
dc->npc = DYNAMIC_PC;
@ -4577,7 +4577,7 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_temp_free(r_pc);
gen_mov_pc_npc(dc, cpu_cond);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_dst, r_const);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
tcg_gen_mov_tl(cpu_npc, cpu_dst);
dc->npc = DYNAMIC_PC;
@ -4592,7 +4592,7 @@ static void disas_sparc_insn(DisasContext * dc)
goto priv_insn;
gen_mov_pc_npc(dc, cpu_cond);
r_const = tcg_const_i32(3);
gen_helper_check_align(cpu_dst, r_const);
gen_helper_check_align(cpu_env, cpu_dst, r_const);
tcg_temp_free_i32(r_const);
tcg_gen_mov_tl(cpu_npc, cpu_dst);
dc->npc = DYNAMIC_PC;
@ -4696,7 +4696,8 @@ static void disas_sparc_insn(DisasContext * dc)
save_state(dc, cpu_cond);
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const); // XXX remove
/* XXX remove alignment check */
gen_helper_check_align(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
gen_address_mask(dc, cpu_addr);
tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
@ -4921,7 +4922,7 @@ static void disas_sparc_insn(DisasContext * dc)
CHECK_FPU_FEATURE(dc, FLOAT128);
r_const = tcg_const_i32(dc->mem_idx);
gen_address_mask(dc, cpu_addr);
gen_helper_ldqf(cpu_addr, r_const);
gen_helper_ldqf(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
gen_op_store_QT0_fpr(QFPREG(rd));
gen_update_fprs_dirty(QFPREG(rd));
@ -4961,7 +4962,8 @@ static void disas_sparc_insn(DisasContext * dc)
save_state(dc, cpu_cond);
gen_address_mask(dc, cpu_addr);
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const); // XXX remove
/* XXX remove alignment check */
gen_helper_check_align(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
gen_movl_reg_TN(rd + 1, cpu_tmp0);
tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
@ -5065,7 +5067,7 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_load_fpr_QT0(QFPREG(rd));
r_const = tcg_const_i32(dc->mem_idx);
gen_address_mask(dc, cpu_addr);
gen_helper_stqf(cpu_addr, r_const);
gen_helper_stqf(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
}
break;
@ -5108,7 +5110,7 @@ static void disas_sparc_insn(DisasContext * dc)
goto jmp_insn;
}
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const);
gen_helper_check_align(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
}
@ -5238,6 +5240,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
int j, lj = -1;
int num_insns;
int max_insns;
unsigned int insn;
memset(dc, 0, sizeof(DisasContext));
dc->tb = tb;
@ -5297,7 +5300,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
last_pc = dc->pc;
disas_sparc_insn(dc);
insn = cpu_ldl_code(env, dc->pc);
disas_sparc_insn(dc, insn);
num_insns++;
if (dc->is_br)

View File

@ -929,6 +929,27 @@ static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -936,6 +957,8 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
@ -943,6 +966,7 @@ static void *qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
#endif
#define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
@ -1075,6 +1099,19 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
# endif
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 bit */
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[2], 0,
tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[1], 0,
tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[0], 0, TCG_AREG0,
SHIFT_IMM_LSL(0));
#endif
tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]);
switch (opc) {
@ -1341,6 +1378,22 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
}
# endif
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 bit */
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[3], 0,
tcg_target_call_iarg_regs[2], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[2], 0,
tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[1], 0,
tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[0], 0, TCG_AREG0,
SHIFT_IMM_LSL(0));
#endif
tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]);
if (opc == 3)
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);

View File

@ -882,6 +882,27 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
#if defined(CONFIG_SOFTMMU)
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -889,12 +910,15 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
__stl_mmu,
__stq_mmu,
};
#endif
/* Load and compare a TLB entry, and branch if TLB miss. OFFSET is set to
the offset of the first ADDR_READ or ADDR_WRITE member of the appropriate
@ -1061,6 +1085,15 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
}
tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call(s, qemu_ld_helpers[opc & 3]);
switch (opc) {
@ -1212,6 +1245,17 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_abort();
}
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call(s, qemu_st_helpers[opc]);
/* label2: */

View File

@ -116,17 +116,7 @@ static inline int tcg_target_get_call_iarg_regs_count(int flags)
return 6;
}
flags &= TCG_CALL_TYPE_MASK;
switch(flags) {
case TCG_CALL_TYPE_STD:
return 0;
case TCG_CALL_TYPE_REGPARM_1:
case TCG_CALL_TYPE_REGPARM_2:
case TCG_CALL_TYPE_REGPARM:
return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
default:
tcg_abort();
}
return 0;
}
/* parse target specific constraints */
@ -188,6 +178,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_set32(ct->u.regs, 0, 0xffff);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
#ifdef CONFIG_TCG_PASS_AREG0
tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDX);
#endif
} else {
tcg_regset_set32(ct->u.regs, 0, 0xff);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
@ -967,6 +960,27 @@ static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void *qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void *qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -974,12 +988,15 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
__stl_mmu,
__stq_mmu,
};
#endif
/* Perform the TLB load and compare.
@ -1148,7 +1165,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int data_reg, data_reg2 = 0;
int addrlo_idx;
#if defined(CONFIG_SOFTMMU)
int mem_index, s_bits, arg_idx;
int mem_index, s_bits;
#if TCG_TARGET_REG_BITS == 64
int arg_idx;
#else
int stack_adjust;
#endif
uint8_t *label_ptr[3];
#endif
@ -1184,16 +1206,48 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
}
/* XXX: move that code at the end of the TB */
#if TCG_TARGET_REG_BITS == 32
tcg_out_pushi(s, mem_index);
stack_adjust = 4;
if (TARGET_LONG_BITS == 64) {
tcg_out_push(s, args[addrlo_idx + 1]);
stack_adjust += 4;
}
tcg_out_push(s, args[addrlo_idx]);
stack_adjust += 4;
#ifdef CONFIG_TCG_PASS_AREG0
tcg_out_push(s, TCG_AREG0);
stack_adjust += 4;
#endif
#else
/* The first argument is already loaded with addrlo. */
arg_idx = 1;
if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++],
args[addrlo_idx + 1]);
}
tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
#endif
tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
#if TCG_TARGET_REG_BITS == 32
if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
/* Pop and discard. This is 2 bytes smaller than the add. */
tcg_out_pop(s, TCG_REG_ECX);
} else if (stack_adjust != 0) {
tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
}
#endif
switch(opc) {
case 0 | 4:
tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
@ -1359,45 +1413,42 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
}
/* XXX: move that code at the end of the TB */
if (TCG_TARGET_REG_BITS == 64) {
tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
TCG_REG_RSI, data_reg);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
stack_adjust = 0;
} else if (TARGET_LONG_BITS == 32) {
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg);
if (opc == 3) {
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg2);
tcg_out_pushi(s, mem_index);
stack_adjust = 4;
} else {
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
stack_adjust = 0;
}
} else {
if (opc == 3) {
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
tcg_out_pushi(s, mem_index);
tcg_out_push(s, data_reg2);
tcg_out_push(s, data_reg);
stack_adjust = 12;
} else {
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, args[addrlo_idx + 1]);
switch(opc) {
case 0:
tcg_out_ext8u(s, TCG_REG_ECX, data_reg);
break;
case 1:
tcg_out_ext16u(s, TCG_REG_ECX, data_reg);
break;
case 2:
tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_ECX, data_reg);
break;
}
tcg_out_pushi(s, mem_index);
stack_adjust = 4;
}
#if TCG_TARGET_REG_BITS == 32
tcg_out_pushi(s, mem_index);
stack_adjust = 4;
if (opc == 3) {
tcg_out_push(s, data_reg2);
stack_adjust += 4;
}
tcg_out_push(s, data_reg);
stack_adjust += 4;
if (TARGET_LONG_BITS == 64) {
tcg_out_push(s, args[addrlo_idx + 1]);
stack_adjust += 4;
}
tcg_out_push(s, args[addrlo_idx]);
stack_adjust += 4;
#ifdef CONFIG_TCG_PASS_AREG0
tcg_out_push(s, TCG_AREG0);
stack_adjust += 4;
#endif
#else
tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
TCG_REG_RSI, data_reg);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
stack_adjust = 0;
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
#endif
tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
@ -1962,9 +2013,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
tcg_out_push(s, tcg_target_callee_save_regs[i]);
}
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
#if TCG_TARGET_REG_BITS == 32
tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
(ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
tcg_out_ld(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[1], TCG_REG_ESP,
(ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4);
#else
tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
#endif
tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
/* jmp *tb. */
tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);

View File

@ -1452,12 +1452,25 @@ static inline void tcg_out_qemu_tlb(TCGContext *s, TCGArg addr_reg,
TCG_REG_P7, TCG_REG_R3, TCG_REG_R57));
}
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
__ldl_mmu,
__ldq_mmu,
};
#endif
static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
{
@ -1517,6 +1530,15 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R2),
tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
}
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
if (!bswap || s_bits == 0) {
tcg_out_bundle(s, miB,
tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
@ -1547,12 +1569,25 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
}
}
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
__stl_mmu,
__stq_mmu,
};
#endif
static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
{
@ -1622,6 +1657,17 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
data_reg = TCG_REG_R2;
}
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_bundle(s, miB,
tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc],
data_reg, TCG_REG_R3),

View File

@ -750,6 +750,27 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -757,6 +778,8 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
@ -764,6 +787,7 @@ static void *qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
#endif
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
int opc)
@ -858,6 +882,15 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
# endif
tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
tcg_out_nop(s);
@ -1069,6 +1102,17 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
}
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 on 32 bit */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
tcg_out_nop(s);

View File

@ -508,6 +508,27 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -515,6 +536,8 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
@ -522,6 +545,7 @@ static void *qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
#endif
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
{
@ -598,6 +622,16 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
#endif
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
switch (opc) {
case 0|4:
@ -829,6 +863,17 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
ir++;
tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
label2_ptr = s->code_ptr;
tcg_out32 (s, B);

View File

@ -98,5 +98,5 @@ typedef enum {
#define TCG_TARGET_HAS_GUEST_BASE
#define tcg_qemu_tb_exec(env, tb_ptr) \
((long REGPARM __attribute__ ((longcall)) \
((long __attribute__ ((longcall)) \
(*)(void *, void *))code_gen_prologue)(env, tb_ptr)

View File

@ -552,6 +552,27 @@ static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -559,12 +580,15 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
__stl_mmu,
__stq_mmu,
};
#endif
static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
int addr_reg, int s_bits, int offset)
@ -648,6 +672,15 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
switch (opc) {
@ -796,6 +829,17 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
label2_ptr = s->code_ptr;

View File

@ -301,6 +301,27 @@ static const uint8_t tcg_cond_to_ltr_cond[10] = {
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static void *qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -308,6 +329,8 @@ static void *qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static void *qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
@ -315,6 +338,7 @@ static void *qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
#endif
static uint8_t *tb_ret_addr;
@ -1483,9 +1507,29 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
tcg_abort();
}
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
} else {
tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
/* sign extension */

View File

@ -59,6 +59,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
};
#endif
#ifdef CONFIG_TCG_PASS_AREG0
#define ARG_OFFSET 1
#else
#define ARG_OFFSET 0
#endif
static const int tcg_target_reg_alloc_order[] = {
TCG_REG_L0,
TCG_REG_L1,
@ -86,9 +92,9 @@ static const int tcg_target_call_iarg_regs[6] = {
static const int tcg_target_call_oarg_regs[] = {
TCG_REG_O0,
#if TCG_TARGET_REG_BITS == 32
TCG_REG_O1
#endif
TCG_REG_O1,
TCG_REG_O2,
TCG_REG_O3,
};
static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
@ -155,6 +161,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
#ifdef CONFIG_TCG_PASS_AREG0
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
#endif
break;
case 'I':
ct->ct |= TCG_CT_CONST_S11;
@ -706,6 +715,27 @@ static void tcg_target_qemu_prologue(TCGContext *s)
#include "../../softmmu_defs.h"
#ifdef CONFIG_TCG_PASS_AREG0
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
#else
/* legacy helper signature: __ld_mmu(target_ulong addr, int
mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
__ldb_mmu,
__ldw_mmu,
@ -713,6 +743,8 @@ static const void * const qemu_ld_helpers[4] = {
__ldq_mmu,
};
/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
__stb_mmu,
__stw_mmu,
@ -720,6 +752,7 @@ static const void * const qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
#endif
#if TARGET_LONG_BITS == 32
#define TARGET_LD_OP LDUW
@ -801,6 +834,17 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
/* mov */
tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
/* XXX: move that code at the end of the TB */
/* qemu_ld_helper[s_bits](arg0, arg1) */

View File

@ -173,11 +173,9 @@ void *tcg_malloc_internal(TCGContext *s, int size)
/* big malloc: insert a new pool (XXX: could optimize) */
p = g_malloc(sizeof(TCGPool) + size);
p->size = size;
if (s->pool_current)
s->pool_current->next = p;
else
s->pool_first = p;
p->next = s->pool_current;
p->next = s->pool_first_large;
s->pool_first_large = p;
return p->data;
} else {
p = s->pool_current;
if (!p) {
@ -208,6 +206,12 @@ void *tcg_malloc_internal(TCGContext *s, int size)
void tcg_pool_reset(TCGContext *s)
{
TCGPool *p, *t;
for (p = s->pool_first_large; p; p = t) {
t = p->next;
g_free(p);
}
s->pool_first_large = NULL;
s->pool_cur = s->pool_end = NULL;
s->pool_current = NULL;
}
@ -590,9 +594,6 @@ void tcg_register_helper(void *func, const char *name)
void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
int sizemask, TCGArg ret, int nargs, TCGArg *args)
{
#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
int call_type;
#endif
int i;
int real_args;
int nb_rets;
@ -617,9 +618,6 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
*gen_opc_ptr++ = INDEX_op_call;
nparam = gen_opparam_ptr++;
#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64
call_type = (flags & TCG_CALL_TYPE_MASK);
#endif
if (ret != TCG_CALL_DUMMY_ARG) {
#if TCG_TARGET_REG_BITS < 64
if (sizemask & 1) {
@ -645,14 +643,6 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
#if TCG_TARGET_REG_BITS < 64
int is_64bit = sizemask & (1 << (i+1)*2);
if (is_64bit) {
#ifdef TCG_TARGET_I386
/* REGPARM case: if the third parameter is 64 bit, it is
allocated on the stack */
if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
call_type = TCG_CALL_TYPE_REGPARM_2;
flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
}
#endif
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
/* some targets want aligned 64 bit args */
if (real_args & 1) {

View File

@ -252,11 +252,6 @@ typedef int TCGv_i64;
#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
/* call flags */
#define TCG_CALL_TYPE_MASK 0x000f
#define TCG_CALL_TYPE_STD 0x0000 /* standard C call */
#define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
#define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
#define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */
/* A pure function only reads its arguments and TCG global variables
and cannot raise exceptions. Hence a call to a pure function can be
safely suppressed if the return value is not used. */
@ -337,7 +332,7 @@ typedef struct TCGContext TCGContext;
struct TCGContext {
uint8_t *pool_cur, *pool_end;
TCGPool *pool_first, *pool_current;
TCGPool *pool_first, *pool_current, *pool_first_large;
TCGLabel *labels;
int nb_labels;
TCGTemp *temps; /* globals first, temps after */
@ -589,5 +584,5 @@ extern uint8_t code_gen_prologue[];
/* TCG targets may use a different definition of tcg_qemu_tb_exec. */
#if !defined(tcg_qemu_tb_exec)
# define tcg_qemu_tb_exec(env, tb_ptr) \
((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
((tcg_target_ulong (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
#endif

View File

@ -798,6 +798,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
case INDEX_op_qemu_st8:
case INDEX_op_qemu_st16:
case INDEX_op_qemu_st32:
#ifdef CONFIG_TCG_PASS_AREG0
tcg_out_r(s, TCG_AREG0);
#endif
tcg_out_r(s, *args++);
tcg_out_r(s, *args++);
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
@ -808,6 +811,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
#endif
break;
case INDEX_op_qemu_st64:
#ifdef CONFIG_TCG_PASS_AREG0
tcg_out_r(s, TCG_AREG0);
#endif
tcg_out_r(s, *args++);
#if TCG_TARGET_REG_BITS == 32
tcg_out_r(s, *args++);

View File

@ -154,7 +154,7 @@ typedef enum {
void tci_disas(uint8_t opc);
unsigned long tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
#define tcg_qemu_tb_exec tcg_qemu_tb_exec
static inline void flush_icache_range(tcg_target_ulong start,

4
tci.c
View File

@ -429,9 +429,9 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
}
/* Interpret pseudo code in tb. */
unsigned long tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
{
unsigned long next_tb = 0;
tcg_target_ulong next_tb = 0;
env = cpustate;
tci_reg[TCG_AREG0] = (tcg_target_ulong)env;