Skip to content

Commit

Permalink
Merge tag 'pull-pa-20231113' of https://gitlab.com/rth7680/qemu into …
Browse files Browse the repository at this point in the history
…staging

target/hppa: Mask reserved PSW bits in expand_sm_imm
target/hppa: Fix calculation of CR_IIASQ back register
target/hppa: Fix possible overflow in TLB size calculation
target/hppa: Fix probe instruction
target/hppa: Split MMU_PHYS_IDX to MMU_ABS_IDX, MMU_ABS_W_IDX
target/hppa: Reduce TARGET_PHYS_ADDR_SPACE_BITS to 40
hw/pci-host/astro: Translate 32-bit pci onto 40-bit runway bus
hw/hppa: Update SeaBIOS-hppa to version 12

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmVSXR4dHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV87qwf+MkEuvMiwqx9YB2qa
# Yhn4m4H1DrQcqGJ2egGuiYrS45JCAUZUcXnmBxL//w3AW7hoeoZwmuFSj+I3EOhI
# y6ykMjMAe8d0VpWEvdkRh7SAWPBKvCJiAclkNyZkYhhagXryiFxqo9tL6nNQQEyz
# HaYzrDwqL+Qgh7/ahkA9XdVLdeTsMtXoLm1cCXpY+TL0MiQonBa1mc17vbyWN8hs
# qWQFBtik0lBIuEN0cB0bUgvV1oH9B8KVUYKbx/RhQORQAiU/O2SaSZ0fxU+F8ynB
# xIyQH6aik0pzgwSo25T/AMxxgUoDydvLDyLCu/R85eNmdgvOj+n4XGIiNEJKEltT
# 1OwGSQ==
# =Qcsh
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 13 Nov 2023 12:30:06 EST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-pa-20231113' of https://gitlab.com/rth7680/qemu:
  hw/hppa: Require at least SeaBIOS-hppa version 12
  target/hppa: Update to SeaBIOS-hppa from version 10 to 12
  hw/hppa: Move software power button address to page zero
  hw/pci-host/astro: Fix boot for C3700 machine
  target/hppa: Reduce TARGET_PHYS_ADDR_SPACE_BITS to 40
  target/hppa: Replace MMU_PHYS_IDX with MMU_ABS_IDX, MMU_ABS_W_IDX
  target/hppa: Introduce MMU_IDX_MMU_DISABLED
  target/hppa: Fix possible overflow in TLB size calculation
  target/hppa: Fix calculation of CR_IIASQ back register
  target/hppa: Use PRIV_P_TO_MMU_IDX in helper_probe
  target/hppa: Use only low 2 immediate bits for PROBEI
  target/hppa: Mask reserved PSW bits in expand_sm_imm

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Nov 14, 2023
2 parents f78ea7d + f88131d commit 3150881
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 119 deletions.
5 changes: 3 additions & 2 deletions hw/hppa/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@
#include "net/net.h"
#include "qemu/log.h"

#define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */
#define MIN_SEABIOS_HPPA_VERSION 12 /* require at least this fw version */

#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
/* Power button address at &PAGE0->pad[4] */
#define HPA_POWER_BUTTON (0x40 + 4 * sizeof(uint32_t))

#define enable_lasi_lan() 0

Expand Down
73 changes: 32 additions & 41 deletions hw/pci-host/astro.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "hw/pci-host/astro.h"
#include "hw/hppa/hppa_hardware.h"
#include "migration/vmstate.h"
#include "target/hppa/cpu.h"
#include "trace.h"
#include "qom/object.h"

Expand Down Expand Up @@ -268,76 +269,66 @@ static const MemoryRegionOps elroy_config_addr_ops = {
};


/*
* A subroutine of astro_translate_iommu that builds an IOMMUTLBEntry using the
* given translated address and mask.
*/
static bool make_iommu_tlbe(hwaddr addr, hwaddr taddr, hwaddr mask,
IOMMUTLBEntry *ret)
{
hwaddr tce_mask = ~((1ull << 12) - 1);
ret->target_as = &address_space_memory;
ret->iova = addr & tce_mask;
ret->translated_addr = taddr & tce_mask;
ret->addr_mask = ~tce_mask;
ret->perm = IOMMU_RW;
return true;
}

/* Handle PCI-to-system address translation. */
static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu,
hwaddr addr,
IOMMUAccessFlags flag,
int iommu_idx)
{
AstroState *s = container_of(iommu, AstroState, iommu);
IOMMUTLBEntry ret = {
.target_as = &address_space_memory,
.iova = addr,
.translated_addr = 0,
.addr_mask = ~(hwaddr)0,
.perm = IOMMU_NONE,
};
hwaddr pdir_ptr, index, a, ibase;
hwaddr pdir_ptr, index, ibase;
hwaddr addr_mask = 0xfff; /* 4k translation */
uint64_t entry;

#define IOVP_SHIFT 12 /* equals PAGE_SHIFT */
#define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT)
#define IOVP_MASK PAGE_MASK
#define SBA_PDIR_VALID_BIT 0x8000000000000000ULL

addr &= ~addr_mask;

/*
* Default translation: "32-bit PCI Addressing on 40-bit Runway".
* For addresses in the 32-bit memory address range ... and then
* language which not-coincidentally matches the PSW.W=0 mapping.
*/
if (addr <= UINT32_MAX) {
entry = hppa_abs_to_phys_pa2_w0(addr);
} else {
entry = addr;
}

/* "range enable" flag cleared? */
if ((s->tlb_ibase & 1) == 0) {
make_iommu_tlbe(addr, addr, addr_mask, &ret);
return ret;
goto skip;
}

a = addr;
ibase = s->tlb_ibase & ~1ULL;
if ((a & s->tlb_imask) != ibase) {
if ((addr & s->tlb_imask) != ibase) {
/* do not translate this one! */
make_iommu_tlbe(addr, addr, addr_mask, &ret);
return ret;
goto skip;
}
index = PDIR_INDEX(a);

index = PDIR_INDEX(addr);
pdir_ptr = s->tlb_pdir_base + index * sizeof(entry);
entry = ldq_le_phys(&address_space_memory, pdir_ptr);

if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */
g_assert_not_reached();
goto failure;
/* failure */
return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
}

entry &= ~SBA_PDIR_VALID_BIT;
entry >>= IOVP_SHIFT;
entry <<= 12;
entry |= addr & 0xfff;
make_iommu_tlbe(addr, entry, addr_mask, &ret);
goto success;

failure:
ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
success:
return ret;
skip:
return (IOMMUTLBEntry) {
.target_as = &address_space_memory,
.iova = addr,
.translated_addr = entry,
.addr_mask = addr_mask,
.perm = IOMMU_RW,
};
}

static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque,
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-host/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))

# HPPA devices
pci_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c'))
specific_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c'))
pci_ss.add(when: 'CONFIG_DINO', if_true: files('dino.c'))

system_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
Expand Down
Binary file modified pc-bios/hppa-firmware.img
Binary file not shown.
2 changes: 1 addition & 1 deletion roms/seabios-hppa
Submodule seabios-hppa updated from fd5b6c to 2a23dd
3 changes: 2 additions & 1 deletion target/hppa/cpu-param.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
# define TARGET_PHYS_ADDR_SPACE_BITS 32
# define TARGET_VIRT_ADDR_SPACE_BITS 32
#else
# define TARGET_PHYS_ADDR_SPACE_BITS 64
/* ??? PA-8000 through 8600 have 40 bits; PA-8700 and 8900 have 44 bits. */
# define TARGET_PHYS_ADDR_SPACE_BITS 40
# define TARGET_VIRT_ADDR_SPACE_BITS 64
#endif

Expand Down
27 changes: 15 additions & 12 deletions target/hppa/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,25 @@
basis. It's probably easier to fall back to a strong memory model. */
#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL

#define MMU_KERNEL_IDX 7
#define MMU_KERNEL_P_IDX 8
#define MMU_PL1_IDX 9
#define MMU_PL1_P_IDX 10
#define MMU_PL2_IDX 11
#define MMU_PL2_P_IDX 12
#define MMU_USER_IDX 13
#define MMU_USER_P_IDX 14
#define MMU_PHYS_IDX 15

#define MMU_ABS_W_IDX 6
#define MMU_ABS_IDX 7
#define MMU_KERNEL_IDX 8
#define MMU_KERNEL_P_IDX 9
#define MMU_PL1_IDX 10
#define MMU_PL1_P_IDX 11
#define MMU_PL2_IDX 12
#define MMU_PL2_P_IDX 13
#define MMU_USER_IDX 14
#define MMU_USER_P_IDX 15

#define MMU_IDX_MMU_DISABLED(MIDX) ((MIDX) < MMU_KERNEL_IDX)
#define MMU_IDX_TO_PRIV(MIDX) (((MIDX) - MMU_KERNEL_IDX) / 2)
#define MMU_IDX_TO_P(MIDX) (((MIDX) - MMU_KERNEL_IDX) & 1)
#define PRIV_P_TO_MMU_IDX(PRIV, P) ((PRIV) * 2 + !!(P) + MMU_KERNEL_IDX)

#define TARGET_INSN_START_EXTRA_WORDS 2

/* No need to flush MMU_PHYS_IDX */
/* No need to flush MMU_ABS*_IDX */
#define HPPA_MMU_FLUSH_MASK \
(1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX | \
1 << MMU_PL1_IDX | 1 << MMU_PL1_P_IDX | \
Expand Down Expand Up @@ -287,7 +289,8 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool ifetch)
if (env->psw & (ifetch ? PSW_C : PSW_D)) {
return PRIV_P_TO_MMU_IDX(env->iaoq_f & 3, env->psw & PSW_P);
}
return MMU_PHYS_IDX; /* mmu disabled */
/* mmu disabled */
return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion target/hppa/int_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void hppa_cpu_do_interrupt(CPUState *cs)
env->cr[CR_IIASQ] =
hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
env->cr_back[0] =
hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
hppa_form_gva_psw(old_psw, env->iasq_b, env->iaoq_b) >> 32;
} else {
env->cr[CR_IIASQ] = 0;
env->cr_back[0] = 0;
Expand Down
97 changes: 57 additions & 40 deletions target/hppa/mem_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,41 +27,39 @@

hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr)
{
if (likely(extract64(addr, 58, 4) != 0xf)) {
/* Memory address space */
return addr & MAKE_64BIT_MASK(0, 62);
}
if (extract64(addr, 54, 4) != 0) {
/* I/O address space */
return addr | MAKE_64BIT_MASK(62, 2);
}
/* PDC address space */
return (addr & MAKE_64BIT_MASK(0, 54)) | MAKE_64BIT_MASK(60, 4);
/*
* Figure H-8 "62-bit Absolute Accesses when PSW W-bit is 1" describes
* an algorithm in which a 62-bit absolute address is transformed to
* a 64-bit physical address. This must then be combined with that
* pictured in Figure H-11 "Physical Address Space Mapping", in which
* the full physical address is truncated to the N-bit physical address
* supported by the implementation.
*
* Since the supported physical address space is below 54 bits, the
* H-8 algorithm is moot and all that is left is to truncate.
*/
QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS);
}

hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr)
{
/*
* See Figure H-10, "Absolute Accesses when PSW W-bit is 0",
* combined with Figure H-11, as above.
*/
if (likely(extract32(addr, 28, 4) != 0xf)) {
/* Memory address space */
return addr & MAKE_64BIT_MASK(0, 32);
}
if (extract32(addr, 24, 4) != 0) {
addr = (uint32_t)addr;
} else if (extract32(addr, 24, 4) != 0) {
/* I/O address space */
return addr | MAKE_64BIT_MASK(32, 32);
}
/* PDC address space */
return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4);
}

static hwaddr hppa_abs_to_phys(CPUHPPAState *env, vaddr addr)
{
if (!hppa_is_pa20(env)) {
return addr;
} else if (env->psw & PSW_W) {
return hppa_abs_to_phys_pa2_w1(addr);
addr = (int32_t)addr;
} else {
return hppa_abs_to_phys_pa2_w0(addr);
/* PDC address space */
addr &= MAKE_64BIT_MASK(0, 24);
addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4);
}
return addr;
}

static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
Expand Down Expand Up @@ -161,9 +159,22 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
*tlb_entry = NULL;
}

/* Virtual translation disabled. Direct map virtual to physical. */
if (mmu_idx == MMU_PHYS_IDX) {
phys = addr;
/* Virtual translation disabled. Map absolute to physical. */
if (MMU_IDX_MMU_DISABLED(mmu_idx)) {
switch (mmu_idx) {
case MMU_ABS_W_IDX:
phys = hppa_abs_to_phys_pa2_w1(addr);
break;
case MMU_ABS_IDX:
if (hppa_is_pa20(env)) {
phys = hppa_abs_to_phys_pa2_w0(addr);
} else {
phys = (uint32_t)addr;
}
break;
default:
g_assert_not_reached();
}
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
goto egress;
}
Expand Down Expand Up @@ -261,7 +272,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
}

egress:
*pphys = phys = hppa_abs_to_phys(env, phys);
*pphys = phys;
*pprot = prot;
trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
return ret;
Expand All @@ -271,16 +282,15 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
HPPACPU *cpu = HPPA_CPU(cs);
hwaddr phys;
int prot, excp;
int prot, excp, mmu_idx;

/* If the (data) mmu is disabled, bypass translation. */
/* ??? We really ought to know if the code mmu is disabled too,
in order to get the correct debugging dumps. */
if (!(cpu->env.psw & PSW_D)) {
return hppa_abs_to_phys(&cpu->env, addr);
}
mmu_idx = (cpu->env.psw & PSW_D ? MMU_KERNEL_IDX :
cpu->env.psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX);

excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0,
excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx, 0,
&phys, &prot, NULL);

/* Since we're translating for debugging, the only error that is a
Expand Down Expand Up @@ -367,8 +377,8 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);

/* Failure. Raise the indicated exception. */
raise_exception_with_ior(env, excp, retaddr,
addr, mmu_idx == MMU_PHYS_IDX);
raise_exception_with_ior(env, excp, retaddr, addr,
MMU_IDX_MMU_DISABLED(mmu_idx));
}

trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
Expand Down Expand Up @@ -450,7 +460,7 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
int mask_shift;

mask_shift = 2 * (r1 & 0xf);
va_size = TARGET_PAGE_SIZE << mask_shift;
va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift;
va_b &= -va_size;
va_e = va_b + va_size - 1;

Expand All @@ -459,7 +469,14 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,

ent->itree.start = va_b;
ent->itree.last = va_e;
ent->pa = (r1 << 7) & (TARGET_PAGE_MASK << mask_shift);

/* Extract all 52 bits present in the page table entry. */
ent->pa = r1 << (TARGET_PAGE_BITS - 5);
/* Align per the page size. */
ent->pa &= TARGET_PAGE_MASK << mask_shift;
/* Ignore the bits beyond physical address space. */
ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS);

ent->t = extract64(r2, 61, 1);
ent->d = extract64(r2, 60, 1);
ent->b = extract64(r2, 59, 1);
Expand Down Expand Up @@ -505,7 +522,7 @@ static void ptlb_work(CPUState *cpu, run_on_cpu_data data)
*/
end = start & 0xf;
start &= TARGET_PAGE_MASK;
end = TARGET_PAGE_SIZE << (2 * end);
end = (vaddr)TARGET_PAGE_SIZE << (2 * end);
end = start + end - 1;

hppa_flush_tlb_range(env, start, end);
Expand Down
5 changes: 3 additions & 2 deletions target/hppa/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ target_ulong HELPER(probe)(CPUHPPAState *env, target_ulong addr,
#ifdef CONFIG_USER_ONLY
return page_check_range(addr, 1, want);
#else
int prot, excp;
int prot, excp, mmu_idx;
hwaddr phys;

trace_hppa_tlb_probe(addr, level, want);
Expand All @@ -347,7 +347,8 @@ target_ulong HELPER(probe)(CPUHPPAState *env, target_ulong addr,
return 0;
}

excp = hppa_get_physical_address(env, addr, level, 0, &phys,
mmu_idx = PRIV_P_TO_MMU_IDX(level, env->psw & PSW_P);
excp = hppa_get_physical_address(env, addr, mmu_idx, 0, &phys,
&prot, NULL);
if (excp >= 0) {
if (env->psw & PSW_Q) {
Expand Down

0 comments on commit 3150881

Please sign in to comment.