Xtensa updates:
- fix register window overflow with l32e/s32e instructions; - make MMU events logging dependent on CPU_LOG_MMU; - attach FLASH to system I/O region on XTFPGA boards; - implement depbits and l32nb instructions. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWJ9qaAAoJEFH5zJH4P6BEQXUQAKfy0crNWrM91HJzvCUxkOKA gNHKlBDsixE0kGlok0gGqiwnKKiPE30au2j4ffzuBhpuzH7laDjrScXZgv4l9fAO odyX6cnw9X7mFoj/8c0f2hQ1gl3vFrx08fA2YjSR5GNmo0yuOyEch4VZzKUQULfs dNjhm+mmgyKNJwuhseuPGP1ttLauX8O9h6cYtMYRxukAjuUWn4LZ05M6Sb9QZmk6 BmKPJxV2EhzXGuNm5s+2Qx7WEfJGtc1bHCUOPJIi249KORVBocp8pe9ZV5BssZdi NHqvJufqmk2sv9hhi+E36sovH05Uf2JgJp6cI5i+C4t4RJT7eMiKQLy3018t4Z2a lkpEnx7u9LgqdKDsvWHMsEkWTQBcnlaj2OK1auTjE+9ey0zXdoP6EtboskHdpVAo q8WzjcADWB/LaeQJ+XTjVvUZHiIDPqzBwNQWFuHiUd9cMz5jMm30G4Vq851kopzu xldmvdo/DjXI52zPIH/mIYsnTh3ivWmmnIhHUZwX6zLdTYEdTq4OZigxCSfq9tYM trA5QxoIWX2QxlzEgajcxDhU9xkUWlElAXwvouu+OVNygPzZy3vr4/GPKF4793vV /3wD0KhvygR5EO0kKQcikC3kFBHVr2S/gUgPnTRDWeSvnxJseVlBc2spdR6fb9P+ Ym3f9v4AtNfG/pm1LzJT =ngur -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/xtensa/tags/20151021-xtensa' into staging Xtensa updates: - fix register window overflow with l32e/s32e instructions; - make MMU events logging dependent on CPU_LOG_MMU; - attach FLASH to system I/O region on XTFPGA boards; - implement depbits and l32nb instructions. # gpg: Signature made Wed 21 Oct 2015 19:34:02 BST using RSA key ID F83FA044 # gpg: Good signature from "Max Filippov <max.filippov@cogentembedded.com>" # gpg: aka "Max Filippov <jcmvbkbc@gmail.com>" * remotes/xtensa/tags/20151021-xtensa: target-xtensa: implement S32NB target-xtensa: implement depbits instruction target-xtensa: xtfpga: attach FLASH to system IO target-xtensa: use CPU_LOG_MMU for MMU event logging target-xtensa: add window overflow check to L32E/S32E Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
c1bd899743
@ -149,6 +149,28 @@ static void lx60_net_init(MemoryRegion *address_space,
|
||||
memory_region_add_subregion(address_space, buffers, ram);
|
||||
}
|
||||
|
||||
static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
|
||||
const LxBoardDesc *board,
|
||||
DriveInfo *dinfo, int be)
|
||||
{
|
||||
SysBusDevice *s;
|
||||
DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
|
||||
|
||||
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
&error_abort);
|
||||
qdev_prop_set_uint32(dev, "num-blocks",
|
||||
board->flash_size / board->flash_sector_size);
|
||||
qdev_prop_set_uint64(dev, "sector-length", board->flash_sector_size);
|
||||
qdev_prop_set_uint8(dev, "width", 4);
|
||||
qdev_prop_set_bit(dev, "big-endian", be);
|
||||
qdev_prop_set_string(dev, "name", "lx60.io.flash");
|
||||
qdev_init_nofail(dev);
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
memory_region_add_subregion(address_space, board->flash_base,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
|
||||
}
|
||||
|
||||
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
|
||||
{
|
||||
XtensaCPU *cpu = opaque;
|
||||
@ -247,16 +269,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
|
||||
|
||||
dinfo = drive_get(IF_PFLASH, 0, 0);
|
||||
if (dinfo) {
|
||||
flash = pflash_cfi01_register(board->flash_base,
|
||||
NULL, "lx60.io.flash", board->flash_size,
|
||||
blk_by_legacy_dinfo(dinfo),
|
||||
board->flash_sector_size,
|
||||
board->flash_size / board->flash_sector_size,
|
||||
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
|
||||
if (flash == NULL) {
|
||||
error_report("unable to mount pflash");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
flash = xtfpga_flash_init(system_io, board, dinfo, be);
|
||||
}
|
||||
|
||||
/* Use presence of kernel file name as 'boot from SRAM' switch. */
|
||||
@ -386,7 +399,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
|
||||
static void xtensa_lx60_init(MachineState *machine)
|
||||
{
|
||||
static const LxBoardDesc lx60_board = {
|
||||
.flash_base = 0xf8000000,
|
||||
.flash_base = 0x08000000,
|
||||
.flash_size = 0x00400000,
|
||||
.flash_sector_size = 0x10000,
|
||||
.sram_size = 0x20000,
|
||||
@ -397,7 +410,7 @@ static void xtensa_lx60_init(MachineState *machine)
|
||||
static void xtensa_lx200_init(MachineState *machine)
|
||||
{
|
||||
static const LxBoardDesc lx200_board = {
|
||||
.flash_base = 0xf8000000,
|
||||
.flash_base = 0x08000000,
|
||||
.flash_size = 0x01000000,
|
||||
.flash_sector_size = 0x20000,
|
||||
.sram_size = 0x2000000,
|
||||
@ -408,7 +421,7 @@ static void xtensa_lx200_init(MachineState *machine)
|
||||
static void xtensa_ml605_init(MachineState *machine)
|
||||
{
|
||||
static const LxBoardDesc ml605_board = {
|
||||
.flash_base = 0xf8000000,
|
||||
.flash_base = 0x08000000,
|
||||
.flash_size = 0x01000000,
|
||||
.flash_sector_size = 0x20000,
|
||||
.sram_size = 0x2000000,
|
||||
@ -419,7 +432,7 @@ static void xtensa_ml605_init(MachineState *machine)
|
||||
static void xtensa_kc705_init(MachineState *machine)
|
||||
{
|
||||
static const LxBoardDesc kc705_board = {
|
||||
.flash_base = 0xf0000000,
|
||||
.flash_base = 0x00000000,
|
||||
.flash_size = 0x08000000,
|
||||
.flash_boot_base = 0x06000000,
|
||||
.flash_sector_size = 0x20000,
|
||||
|
@ -64,6 +64,7 @@ enum {
|
||||
XTENSA_OPTION_MP_SYNCHRO,
|
||||
XTENSA_OPTION_CONDITIONAL_STORE,
|
||||
XTENSA_OPTION_ATOMCTL,
|
||||
XTENSA_OPTION_DEPBITS,
|
||||
|
||||
/* Interrupts and exceptions */
|
||||
XTENSA_OPTION_EXCEPTION,
|
||||
|
@ -541,8 +541,8 @@ static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
|
||||
wi = ++env->autorefill_idx & 0x3;
|
||||
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
|
||||
env->sregs[EXCVADDR] = vaddr;
|
||||
qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
|
||||
__func__, vaddr, vpn, pte);
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n",
|
||||
__func__, vaddr, vpn, pte);
|
||||
} else {
|
||||
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
|
||||
entry = &tmp_entry;
|
||||
@ -590,8 +590,8 @@ static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte)
|
||||
int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
|
||||
&paddr, &page_size, &access, false);
|
||||
|
||||
qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__,
|
||||
vaddr, ret ? ~0 : paddr);
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s: trying autorefill(%08x) -> %08x\n",
|
||||
__func__, vaddr, ret ? ~0 : paddr);
|
||||
|
||||
if (ret == 0) {
|
||||
*pte = ldl_phys(cs->as, paddr);
|
||||
|
@ -57,8 +57,8 @@ void tlb_fill(CPUState *cs,
|
||||
int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
|
||||
&paddr, &page_size, &access);
|
||||
|
||||
qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__,
|
||||
vaddr, is_write, mmu_idx, paddr, ret);
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
|
||||
__func__, vaddr, is_write, mmu_idx, paddr, ret);
|
||||
|
||||
if (ret == 0) {
|
||||
tlb_set_page(cs,
|
||||
|
@ -30,6 +30,10 @@
|
||||
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
|
||||
#define XTREG_END { .targno = -1 },
|
||||
|
||||
#ifndef XCHAL_HAVE_DEPBITS
|
||||
#define XCHAL_HAVE_DEPBITS 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_HAVE_DIV32
|
||||
#define XCHAL_HAVE_DIV32 0
|
||||
#endif
|
||||
@ -69,6 +73,7 @@
|
||||
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
|
||||
XTENSA_OPTION_ATOMCTL) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \
|
||||
/* Interrupts and exceptions */ \
|
||||
XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \
|
||||
|
@ -1943,7 +1943,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
switch (OP2) {
|
||||
case 0: /*L32E*/
|
||||
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
|
||||
if (gen_check_privilege(dc)) {
|
||||
if (gen_check_privilege(dc) &&
|
||||
gen_window_check2(dc, RRR_S, RRR_T)) {
|
||||
TCGv_i32 addr = tcg_temp_new_i32();
|
||||
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
|
||||
(0xffffffc0 | (RRR_R << 2)));
|
||||
@ -1954,7 +1955,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
|
||||
case 4: /*S32E*/
|
||||
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
|
||||
if (gen_check_privilege(dc)) {
|
||||
if (gen_check_privilege(dc) &&
|
||||
gen_window_check2(dc, RRR_S, RRR_T)) {
|
||||
TCGv_i32 addr = tcg_temp_new_i32();
|
||||
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
|
||||
(0xffffffc0 | (RRR_R << 2)));
|
||||
@ -1963,6 +1965,17 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /*S32N*/
|
||||
if (gen_window_check2(dc, RRI4_S, RRI4_T)) {
|
||||
TCGv_i32 addr = tcg_temp_new_i32();
|
||||
|
||||
tcg_gen_addi_i32(addr, cpu_R[RRI4_S], RRI4_IMM4 << 2);
|
||||
gen_load_store_alignment(dc, 2, addr, false);
|
||||
tcg_gen_qemu_st32(cpu_R[RRI4_T], addr, dc->cring);
|
||||
tcg_temp_free(addr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
RESERVED();
|
||||
break;
|
||||
@ -1970,6 +1983,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
break;
|
||||
|
||||
case 10: /*FP0*/
|
||||
/*DEPBITS*/
|
||||
if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
|
||||
if (!gen_window_check2(dc, RRR_S, RRR_T)) {
|
||||
break;
|
||||
}
|
||||
tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
|
||||
OP2, RRR_R + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
|
||||
switch (OP2) {
|
||||
case 0: /*ADD.Sf*/
|
||||
@ -2104,6 +2127,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
break;
|
||||
|
||||
case 11: /*FP1*/
|
||||
/*DEPBITS*/
|
||||
if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
|
||||
if (!gen_window_check2(dc, RRR_S, RRR_T)) {
|
||||
break;
|
||||
}
|
||||
tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
|
||||
OP2 + 16, RRR_R + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
|
||||
|
||||
#define gen_compare(rel, br, a, b) \
|
||||
|
Loading…
Reference in New Issue
Block a user