Am 1. März 2025 16:10:35 UTC schrieb BALATON Zoltan <bala...@eik.bme.hu>:
>On Wed, 15 Jan 2025, BALATON Zoltan wrote:
>> This allows guests to set the CCSR base address. Also store and return
>> values of the local access window registers but their functionality
>> isn't implemented.
>
>Bernhard,

Hi Zoltan,

>
>If you have no alternative patch you plan to submit for next release should we 
>merge this for now? This helps running u-boot binaries even if it's not enough 
>alone but would be one patch less in my local tree. Or do you know about a 
>problem with this patch why this should not be merged?

QEMU sets a machine-specific CCSR base address (pmc->ccsrbar_base) which 
differs from the real chip's default. The default is checked by U-Boot which 
enters an infinite loop on mismatch: 
<https://source.denx.de/u-boot/u-boot/-/blob/v2024.07/arch/powerpc/cpu/mpc85xx/start.S#L614>.
 How does this work for you?

In addition, when moving the CCSR region, `env->mpic_iack` should be updated as 
well: 
<https://gitlab.com/qemu-project/qemu/-/blob/v9.2.2/hw/ppc/e500.c?ref_type=tags#L969>

I'm happy to submit an implementation on top of my e500 cleanup series 
<https://patchew.org/QEMU/20241103133412.73536-1-shen...@gmail.com/> which 
needs agreement on some open discussions.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: BALATON Zoltan <bala...@eik.bme.hu>
>> ---
>> hw/ppc/e500-ccsr.h |  4 +++
>> hw/ppc/e500.c      | 79 ++++++++++++++++++++++++++++++++++++++++++++--
>> 2 files changed, 80 insertions(+), 3 deletions(-)
>> 
>> diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h
>> index 249c17be3b..cfbf96e181 100644
>> --- a/hw/ppc/e500-ccsr.h
>> +++ b/hw/ppc/e500-ccsr.h
>> @@ -4,12 +4,16 @@
>> #include "hw/sysbus.h"
>> #include "qom/object.h"
>> 
>> +#define NR_LAWS 12
>> +
>> struct PPCE500CCSRState {
>>     /*< private >*/
>>     SysBusDevice parent;
>>     /*< public >*/
>> 
>>     MemoryRegion ccsr_space;
>> +
>> +    uint32_t law_regs[NR_LAWS * 2];
>> };
>> 
>> #define TYPE_CCSR "e500-ccsr"
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 64f8c766b4..376cb4cb37 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -43,6 +43,7 @@
>> #include "qemu/host-utils.h"
>> #include "qemu/option.h"
>> #include "hw/pci-host/ppce500.h"
>> +#include "qemu/log.h"
>> #include "qemu/error-report.h"
>> #include "hw/platform-bus.h"
>> #include "hw/net/fsl_etsec/etsec.h"
>> @@ -1331,11 +1332,83 @@ void ppce500_init(MachineState *machine)
>>     boot_info->dt_size = dt_size;
>> }
>> 
>> +static int law_idx(hwaddr addr)
>> +{
>> +    int idx;
>> +
>> +    addr -= 0xc08;
>> +    idx = 2 * ((addr >> 5) & 0xf);
>> +    if (addr & 8) {
>> +        idx++;
>> +    }
>> +    assert(idx < 2 * NR_LAWS);
>> +    return idx;
>> +}
>> +
>> +static uint64_t law_read(void *opaque, hwaddr addr, unsigned size)
>> +{
>> +    PPCE500CCSRState *s = opaque;
>> +    uint64_t val = 0;
>> +
>> +    switch (addr) {
>> +    case 0:
>> +        val = s->ccsr_space.addr >> 12;
>> +        break;
>> +    case 0xc08 ... 0xd70:
>> +        val = s->law_regs[law_idx(addr)];
>> +        break;
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR, "Invalid local access register read"
>> +                      "0x%" HWADDR_PRIx "\n", addr);
>> +    }
>> +    return val;
>> +}
>> +
>> +static void law_write(void *opaque, hwaddr addr, uint64_t val, unsigned 
>> size)
>> +{
>> +    PPCE500CCSRState *s = opaque;
>> +
>> +    switch (addr) {
>> +    case 0:
>> +        val &= 0xffff00;
>> +        memory_region_set_address(&s->ccsr_space, val << 12);
>> +        break;
>> +    case 0xc08 ... 0xd70:
>> +    {
>> +        int idx = law_idx(addr);
>> +
>> +        qemu_log_mask(LOG_UNIMP, "Unimplemented local access register write"
>> +                      "0x%" HWADDR_PRIx " <- 0x%" PRIx64 "\n", addr, val);
>> +        val &= (idx & 1) ? 0x80f0003f : 0xffffff;
>> +        s->law_regs[idx] = val;
>> +        break;
>> +    }
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR, "Invalid local access register write"
>> +                      "0x%" HWADDR_PRIx "\n", addr);
>> +    }
>> +}
>> +
>> +static const MemoryRegionOps law_ops = {
>> +    .read = law_read,
>> +    .write = law_write,
>> +    .endianness = DEVICE_BIG_ENDIAN,
>> +    .valid = {
>> +        .min_access_size = 4,
>> +        .max_access_size = 4,
>> +    },
>> +};
>> +
>> static void e500_ccsr_initfn(Object *obj)
>> {
>> -    PPCE500CCSRState *ccsr = CCSR(obj);
>> -    memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
>> -                       MPC8544_CCSRBAR_SIZE);
>> +    PPCE500CCSRState *s = CCSR(obj);
>> +    MemoryRegion *mr;
>> +
>> +    memory_region_init(&s->ccsr_space, obj, "e500-ccsr", 
>> MPC8544_CCSRBAR_SIZE);
>> +
>> +    mr = g_new(MemoryRegion, 1);
>> +    memory_region_init_io(mr, obj, &law_ops, s, "local-access", 4096);
>> +    memory_region_add_subregion(&s->ccsr_space, 0, mr);
>> }
>> 
>> static const TypeInfo e500_ccsr_info = {
>> 

Reply via email to