xref: /qemu/hw/misc/armsse-cpuid.c (revision a27bd6c779badb8d76e4430d810ef710a1b98f4e)
15aeb3689SPeter Maydell /*
25aeb3689SPeter Maydell  * ARM SSE-200 CPU_IDENTITY register block
35aeb3689SPeter Maydell  *
45aeb3689SPeter Maydell  * Copyright (c) 2019 Linaro Limited
55aeb3689SPeter Maydell  * Written by Peter Maydell
65aeb3689SPeter Maydell  *
75aeb3689SPeter Maydell  *  This program is free software; you can redistribute it and/or modify
85aeb3689SPeter Maydell  *  it under the terms of the GNU General Public License version 2 or
95aeb3689SPeter Maydell  *  (at your option) any later version.
105aeb3689SPeter Maydell  */
115aeb3689SPeter Maydell 
125aeb3689SPeter Maydell /*
135aeb3689SPeter Maydell  * This is a model of the "CPU_IDENTITY" register block which is part of the
145aeb3689SPeter Maydell  * Arm SSE-200 and documented in
155aeb3689SPeter Maydell  * 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
165aeb3689SPeter Maydell  *
175aeb3689SPeter Maydell  * It consists of one read-only CPUID register (set by QOM property), plus the
185aeb3689SPeter Maydell  * usual ID registers.
195aeb3689SPeter Maydell  */
205aeb3689SPeter Maydell 
215aeb3689SPeter Maydell #include "qemu/osdep.h"
225aeb3689SPeter Maydell #include "qemu/log.h"
230b8fa32fSMarkus Armbruster #include "qemu/module.h"
245aeb3689SPeter Maydell #include "trace.h"
255aeb3689SPeter Maydell #include "qapi/error.h"
265aeb3689SPeter Maydell #include "sysemu/sysemu.h"
275aeb3689SPeter Maydell #include "hw/sysbus.h"
285aeb3689SPeter Maydell #include "hw/registerfields.h"
295aeb3689SPeter Maydell #include "hw/misc/armsse-cpuid.h"
30*a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
315aeb3689SPeter Maydell 
325aeb3689SPeter Maydell REG32(CPUID, 0x0)
335aeb3689SPeter Maydell REG32(PID4, 0xfd0)
345aeb3689SPeter Maydell REG32(PID5, 0xfd4)
355aeb3689SPeter Maydell REG32(PID6, 0xfd8)
365aeb3689SPeter Maydell REG32(PID7, 0xfdc)
375aeb3689SPeter Maydell REG32(PID0, 0xfe0)
385aeb3689SPeter Maydell REG32(PID1, 0xfe4)
395aeb3689SPeter Maydell REG32(PID2, 0xfe8)
405aeb3689SPeter Maydell REG32(PID3, 0xfec)
415aeb3689SPeter Maydell REG32(CID0, 0xff0)
425aeb3689SPeter Maydell REG32(CID1, 0xff4)
435aeb3689SPeter Maydell REG32(CID2, 0xff8)
445aeb3689SPeter Maydell REG32(CID3, 0xffc)
455aeb3689SPeter Maydell 
465aeb3689SPeter Maydell /* PID/CID values */
475aeb3689SPeter Maydell static const int sysinfo_id[] = {
485aeb3689SPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
495aeb3689SPeter Maydell     0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
505aeb3689SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
515aeb3689SPeter Maydell };
525aeb3689SPeter Maydell 
535aeb3689SPeter Maydell static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
545aeb3689SPeter Maydell                                     unsigned size)
555aeb3689SPeter Maydell {
565aeb3689SPeter Maydell     ARMSSECPUID *s = ARMSSE_CPUID(opaque);
575aeb3689SPeter Maydell     uint64_t r;
585aeb3689SPeter Maydell 
595aeb3689SPeter Maydell     switch (offset) {
605aeb3689SPeter Maydell     case A_CPUID:
615aeb3689SPeter Maydell         r = s->cpuid;
625aeb3689SPeter Maydell         break;
635aeb3689SPeter Maydell     case A_PID4 ... A_CID3:
645aeb3689SPeter Maydell         r = sysinfo_id[(offset - A_PID4) / 4];
655aeb3689SPeter Maydell         break;
665aeb3689SPeter Maydell     default:
675aeb3689SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
685aeb3689SPeter Maydell                       "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
695aeb3689SPeter Maydell         r = 0;
705aeb3689SPeter Maydell         break;
715aeb3689SPeter Maydell     }
725aeb3689SPeter Maydell     trace_armsse_cpuid_read(offset, r, size);
735aeb3689SPeter Maydell     return r;
745aeb3689SPeter Maydell }
755aeb3689SPeter Maydell 
765aeb3689SPeter Maydell static void armsse_cpuid_write(void *opaque, hwaddr offset,
775aeb3689SPeter Maydell                                  uint64_t value, unsigned size)
785aeb3689SPeter Maydell {
795aeb3689SPeter Maydell     trace_armsse_cpuid_write(offset, value, size);
805aeb3689SPeter Maydell 
815aeb3689SPeter Maydell     qemu_log_mask(LOG_GUEST_ERROR,
825aeb3689SPeter Maydell                   "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
835aeb3689SPeter Maydell }
845aeb3689SPeter Maydell 
855aeb3689SPeter Maydell static const MemoryRegionOps armsse_cpuid_ops = {
865aeb3689SPeter Maydell     .read = armsse_cpuid_read,
875aeb3689SPeter Maydell     .write = armsse_cpuid_write,
885aeb3689SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
895aeb3689SPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
905aeb3689SPeter Maydell     .impl.min_access_size = 4,
915aeb3689SPeter Maydell     .impl.max_access_size = 4,
925aeb3689SPeter Maydell     .valid.min_access_size = 1,
935aeb3689SPeter Maydell     .valid.max_access_size = 4,
945aeb3689SPeter Maydell };
955aeb3689SPeter Maydell 
965aeb3689SPeter Maydell static Property armsse_cpuid_props[] = {
975aeb3689SPeter Maydell     DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
985aeb3689SPeter Maydell     DEFINE_PROP_END_OF_LIST()
995aeb3689SPeter Maydell };
1005aeb3689SPeter Maydell 
1015aeb3689SPeter Maydell static void armsse_cpuid_init(Object *obj)
1025aeb3689SPeter Maydell {
1035aeb3689SPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1045aeb3689SPeter Maydell     ARMSSECPUID *s = ARMSSE_CPUID(obj);
1055aeb3689SPeter Maydell 
1065aeb3689SPeter Maydell     memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
1075aeb3689SPeter Maydell                           s, "armsse-cpuid", 0x1000);
1085aeb3689SPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
1095aeb3689SPeter Maydell }
1105aeb3689SPeter Maydell 
1115aeb3689SPeter Maydell static void armsse_cpuid_class_init(ObjectClass *klass, void *data)
1125aeb3689SPeter Maydell {
1135aeb3689SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
1145aeb3689SPeter Maydell 
1155aeb3689SPeter Maydell     /*
1165aeb3689SPeter Maydell      * This device has no guest-modifiable state and so it
1175aeb3689SPeter Maydell      * does not need a reset function or VMState.
1185aeb3689SPeter Maydell      */
1195aeb3689SPeter Maydell 
1205aeb3689SPeter Maydell     dc->props = armsse_cpuid_props;
1215aeb3689SPeter Maydell }
1225aeb3689SPeter Maydell 
1235aeb3689SPeter Maydell static const TypeInfo armsse_cpuid_info = {
1245aeb3689SPeter Maydell     .name = TYPE_ARMSSE_CPUID,
1255aeb3689SPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
1265aeb3689SPeter Maydell     .instance_size = sizeof(ARMSSECPUID),
1275aeb3689SPeter Maydell     .instance_init = armsse_cpuid_init,
1285aeb3689SPeter Maydell     .class_init = armsse_cpuid_class_init,
1295aeb3689SPeter Maydell };
1305aeb3689SPeter Maydell 
1315aeb3689SPeter Maydell static void armsse_cpuid_register_types(void)
1325aeb3689SPeter Maydell {
1335aeb3689SPeter Maydell     type_register_static(&armsse_cpuid_info);
1345aeb3689SPeter Maydell }
1355aeb3689SPeter Maydell 
1365aeb3689SPeter Maydell type_init(armsse_cpuid_register_types);
137