/*
 * ARM SSE-200 CPU_IDENTITY register block
 *
 * Copyright (c) 2019 Linaro Limited
 * Written by Peter Maydell
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 or
 *  (at your option) any later version.
 */

/*
 * This is a model of the "CPU_IDENTITY" register block which is part of the
 * Arm SSE-200 and documented in
 * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
 *
 * It consists of one read-only CPUID register (set by QOM property), plus the
 * usual ID registers.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "trace.h"
#include "qapi/error.h"
#include "sysemu/sysemu.h"
#include "hw/sysbus.h"
#include "hw/registerfields.h"
#include "hw/misc/armsse-cpuid.h"

REG32(CPUID, 0x0)
REG32(PID4, 0xfd0)
REG32(PID5, 0xfd4)
REG32(PID6, 0xfd8)
REG32(PID7, 0xfdc)
REG32(PID0, 0xfe0)
REG32(PID1, 0xfe4)
REG32(PID2, 0xfe8)
REG32(PID3, 0xfec)
REG32(CID0, 0xff0)
REG32(CID1, 0xff4)
REG32(CID2, 0xff8)
REG32(CID3, 0xffc)

/* PID/CID values */
static const int sysinfo_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
                                    unsigned size)
{
    ARMSSECPUID *s = ARMSSE_CPUID(opaque);
    uint64_t r;

    switch (offset) {
    case A_CPUID:
        r = s->cpuid;
        break;
    case A_PID4 ... A_CID3:
        r = sysinfo_id[(offset - A_PID4) / 4];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
        r = 0;
        break;
    }
    trace_armsse_cpuid_read(offset, r, size);
    return r;
}

static void armsse_cpuid_write(void *opaque, hwaddr offset,
                                 uint64_t value, unsigned size)
{
    trace_armsse_cpuid_write(offset, value, size);

    qemu_log_mask(LOG_GUEST_ERROR,
                  "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
}

static const MemoryRegionOps armsse_cpuid_ops = {
    .read = armsse_cpuid_read,
    .write = armsse_cpuid_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    /* byte/halfword accesses are just zero-padded on reads and writes */
    .impl.min_access_size = 4,
    .impl.max_access_size = 4,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
};

static Property armsse_cpuid_props[] = {
    DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
    DEFINE_PROP_END_OF_LIST()
};

static void armsse_cpuid_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    ARMSSECPUID *s = ARMSSE_CPUID(obj);

    memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
                          s, "armsse-cpuid", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
}

static void armsse_cpuid_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    /*
     * This device has no guest-modifiable state and so it
     * does not need a reset function or VMState.
     */

    dc->props = armsse_cpuid_props;
}

static const TypeInfo armsse_cpuid_info = {
    .name = TYPE_ARMSSE_CPUID,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(ARMSSECPUID),
    .instance_init = armsse_cpuid_init,
    .class_init = armsse_cpuid_class_init,
};

static void armsse_cpuid_register_types(void)
{
    type_register_static(&armsse_cpuid_info);
}

type_init(armsse_cpuid_register_types);
