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:
Peter Maydell 2015-10-21 21:21:29 +01:00
commit c1bd899743
6 changed files with 74 additions and 22 deletions

View File

@ -149,6 +149,28 @@ static void lx60_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram); 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) static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
{ {
XtensaCPU *cpu = opaque; XtensaCPU *cpu = opaque;
@ -247,16 +269,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0); dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) { if (dinfo) {
flash = pflash_cfi01_register(board->flash_base, flash = xtfpga_flash_init(system_io, board, dinfo, be);
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);
}
} }
/* Use presence of kernel file name as 'boot from SRAM' switch. */ /* 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 void xtensa_lx60_init(MachineState *machine)
{ {
static const LxBoardDesc lx60_board = { static const LxBoardDesc lx60_board = {
.flash_base = 0xf8000000, .flash_base = 0x08000000,
.flash_size = 0x00400000, .flash_size = 0x00400000,
.flash_sector_size = 0x10000, .flash_sector_size = 0x10000,
.sram_size = 0x20000, .sram_size = 0x20000,
@ -397,7 +410,7 @@ static void xtensa_lx60_init(MachineState *machine)
static void xtensa_lx200_init(MachineState *machine) static void xtensa_lx200_init(MachineState *machine)
{ {
static const LxBoardDesc lx200_board = { static const LxBoardDesc lx200_board = {
.flash_base = 0xf8000000, .flash_base = 0x08000000,
.flash_size = 0x01000000, .flash_size = 0x01000000,
.flash_sector_size = 0x20000, .flash_sector_size = 0x20000,
.sram_size = 0x2000000, .sram_size = 0x2000000,
@ -408,7 +421,7 @@ static void xtensa_lx200_init(MachineState *machine)
static void xtensa_ml605_init(MachineState *machine) static void xtensa_ml605_init(MachineState *machine)
{ {
static const LxBoardDesc ml605_board = { static const LxBoardDesc ml605_board = {
.flash_base = 0xf8000000, .flash_base = 0x08000000,
.flash_size = 0x01000000, .flash_size = 0x01000000,
.flash_sector_size = 0x20000, .flash_sector_size = 0x20000,
.sram_size = 0x2000000, .sram_size = 0x2000000,
@ -419,7 +432,7 @@ static void xtensa_ml605_init(MachineState *machine)
static void xtensa_kc705_init(MachineState *machine) static void xtensa_kc705_init(MachineState *machine)
{ {
static const LxBoardDesc kc705_board = { static const LxBoardDesc kc705_board = {
.flash_base = 0xf0000000, .flash_base = 0x00000000,
.flash_size = 0x08000000, .flash_size = 0x08000000,
.flash_boot_base = 0x06000000, .flash_boot_base = 0x06000000,
.flash_sector_size = 0x20000, .flash_sector_size = 0x20000,

View File

@ -64,6 +64,7 @@ enum {
XTENSA_OPTION_MP_SYNCHRO, XTENSA_OPTION_MP_SYNCHRO,
XTENSA_OPTION_CONDITIONAL_STORE, XTENSA_OPTION_CONDITIONAL_STORE,
XTENSA_OPTION_ATOMCTL, XTENSA_OPTION_ATOMCTL,
XTENSA_OPTION_DEPBITS,
/* Interrupts and exceptions */ /* Interrupts and exceptions */
XTENSA_OPTION_EXCEPTION, XTENSA_OPTION_EXCEPTION,

View File

@ -541,8 +541,8 @@ static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
wi = ++env->autorefill_idx & 0x3; wi = ++env->autorefill_idx & 0x3;
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte); xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
env->sregs[EXCVADDR] = vaddr; env->sregs[EXCVADDR] = vaddr;
qemu_log("%s: autorefill(%08x): %08x -> %08x\n", qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n",
__func__, vaddr, vpn, pte); __func__, vaddr, vpn, pte);
} else { } else {
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte); xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
entry = &tmp_entry; 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, int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
&paddr, &page_size, &access, false); &paddr, &page_size, &access, false);
qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__, qemu_log_mask(CPU_LOG_MMU, "%s: trying autorefill(%08x) -> %08x\n",
vaddr, ret ? ~0 : paddr); __func__, vaddr, ret ? ~0 : paddr);
if (ret == 0) { if (ret == 0) {
*pte = ldl_phys(cs->as, paddr); *pte = ldl_phys(cs->as, paddr);

View File

@ -57,8 +57,8 @@ void tlb_fill(CPUState *cs,
int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx, int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
&paddr, &page_size, &access); &paddr, &page_size, &access);
qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__, qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
vaddr, is_write, mmu_idx, paddr, ret); __func__, vaddr, is_write, mmu_idx, paddr, ret);
if (ret == 0) { if (ret == 0) {
tlb_set_page(cs, tlb_set_page(cs,

View File

@ -30,6 +30,10 @@
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) }, { .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
#define XTREG_END { .targno = -1 }, #define XTREG_END { .targno = -1 },
#ifndef XCHAL_HAVE_DEPBITS
#define XCHAL_HAVE_DEPBITS 0
#endif
#ifndef XCHAL_HAVE_DIV32 #ifndef XCHAL_HAVE_DIV32
#define XCHAL_HAVE_DIV32 0 #define XCHAL_HAVE_DIV32 0
#endif #endif
@ -69,6 +73,7 @@
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \ XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \ XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
XTENSA_OPTION_ATOMCTL) | \ XTENSA_OPTION_ATOMCTL) | \
XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \
/* Interrupts and exceptions */ \ /* Interrupts and exceptions */ \
XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \ XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \ XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \

View File

@ -1943,7 +1943,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
switch (OP2) { switch (OP2) {
case 0: /*L32E*/ case 0: /*L32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 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(); TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S], tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2))); (0xffffffc0 | (RRR_R << 2)));
@ -1954,7 +1955,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 4: /*S32E*/ case 4: /*S32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); 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(); TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S], tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2))); (0xffffffc0 | (RRR_R << 2)));
@ -1963,6 +1965,17 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
} }
break; 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: default:
RESERVED(); RESERVED();
break; break;
@ -1970,6 +1983,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break; break;
case 10: /*FP0*/ 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); HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
switch (OP2) { switch (OP2) {
case 0: /*ADD.Sf*/ case 0: /*ADD.Sf*/
@ -2104,6 +2127,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break; break;
case 11: /*FP1*/ 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); HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
#define gen_compare(rel, br, a, b) \ #define gen_compare(rel, br, a, b) \