[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] hw/ppc/e500: Partial implementation of local access window regis
From: |
BALATON Zoltan |
Subject: |
[PATCH] hw/ppc/e500: Partial implementation of local access window registers |
Date: |
Wed, 15 Jan 2025 22:15:44 +0100 (CET) |
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.
Signed-off-by: BALATON Zoltan <balaton@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 = {
--
2.30.9
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] hw/ppc/e500: Partial implementation of local access window registers,
BALATON Zoltan <=