xref: /qemu/hw/misc/armsse-cpuid.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
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
1550b52b18SPeter Maydell  * https://developer.arm.com/documentation/101104/latest/
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 "hw/sysbus.h"
275aeb3689SPeter Maydell #include "hw/registerfields.h"
285aeb3689SPeter Maydell #include "hw/misc/armsse-cpuid.h"
29a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
305aeb3689SPeter Maydell 
315aeb3689SPeter Maydell REG32(CPUID, 0x0)
325aeb3689SPeter Maydell REG32(PID4, 0xfd0)
335aeb3689SPeter Maydell REG32(PID5, 0xfd4)
345aeb3689SPeter Maydell REG32(PID6, 0xfd8)
355aeb3689SPeter Maydell REG32(PID7, 0xfdc)
365aeb3689SPeter Maydell REG32(PID0, 0xfe0)
375aeb3689SPeter Maydell REG32(PID1, 0xfe4)
385aeb3689SPeter Maydell REG32(PID2, 0xfe8)
395aeb3689SPeter Maydell REG32(PID3, 0xfec)
405aeb3689SPeter Maydell REG32(CID0, 0xff0)
415aeb3689SPeter Maydell REG32(CID1, 0xff4)
425aeb3689SPeter Maydell REG32(CID2, 0xff8)
435aeb3689SPeter Maydell REG32(CID3, 0xffc)
445aeb3689SPeter Maydell 
455aeb3689SPeter Maydell /* PID/CID values */
465aeb3689SPeter Maydell static const int sysinfo_id[] = {
475aeb3689SPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
485aeb3689SPeter Maydell     0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
495aeb3689SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
505aeb3689SPeter Maydell };
515aeb3689SPeter Maydell 
armsse_cpuid_read(void * opaque,hwaddr offset,unsigned size)525aeb3689SPeter Maydell static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
535aeb3689SPeter Maydell                                     unsigned size)
545aeb3689SPeter Maydell {
555aeb3689SPeter Maydell     ARMSSECPUID *s = ARMSSE_CPUID(opaque);
565aeb3689SPeter Maydell     uint64_t r;
575aeb3689SPeter Maydell 
585aeb3689SPeter Maydell     switch (offset) {
595aeb3689SPeter Maydell     case A_CPUID:
605aeb3689SPeter Maydell         r = s->cpuid;
615aeb3689SPeter Maydell         break;
625aeb3689SPeter Maydell     case A_PID4 ... A_CID3:
635aeb3689SPeter Maydell         r = sysinfo_id[(offset - A_PID4) / 4];
645aeb3689SPeter Maydell         break;
655aeb3689SPeter Maydell     default:
665aeb3689SPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
675aeb3689SPeter Maydell                       "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
685aeb3689SPeter Maydell         r = 0;
695aeb3689SPeter Maydell         break;
705aeb3689SPeter Maydell     }
715aeb3689SPeter Maydell     trace_armsse_cpuid_read(offset, r, size);
725aeb3689SPeter Maydell     return r;
735aeb3689SPeter Maydell }
745aeb3689SPeter Maydell 
armsse_cpuid_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)755aeb3689SPeter Maydell static void armsse_cpuid_write(void *opaque, hwaddr offset,
765aeb3689SPeter Maydell                                  uint64_t value, unsigned size)
775aeb3689SPeter Maydell {
785aeb3689SPeter Maydell     trace_armsse_cpuid_write(offset, value, size);
795aeb3689SPeter Maydell 
805aeb3689SPeter Maydell     qemu_log_mask(LOG_GUEST_ERROR,
815aeb3689SPeter Maydell                   "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
825aeb3689SPeter Maydell }
835aeb3689SPeter Maydell 
845aeb3689SPeter Maydell static const MemoryRegionOps armsse_cpuid_ops = {
855aeb3689SPeter Maydell     .read = armsse_cpuid_read,
865aeb3689SPeter Maydell     .write = armsse_cpuid_write,
875aeb3689SPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
885aeb3689SPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
895aeb3689SPeter Maydell     .impl.min_access_size = 4,
905aeb3689SPeter Maydell     .impl.max_access_size = 4,
915aeb3689SPeter Maydell     .valid.min_access_size = 1,
925aeb3689SPeter Maydell     .valid.max_access_size = 4,
935aeb3689SPeter Maydell };
945aeb3689SPeter Maydell 
9530029973SRichard Henderson static const Property armsse_cpuid_props[] = {
965aeb3689SPeter Maydell     DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
975aeb3689SPeter Maydell };
985aeb3689SPeter Maydell 
armsse_cpuid_init(Object * obj)995aeb3689SPeter Maydell static void armsse_cpuid_init(Object *obj)
1005aeb3689SPeter Maydell {
1015aeb3689SPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1025aeb3689SPeter Maydell     ARMSSECPUID *s = ARMSSE_CPUID(obj);
1035aeb3689SPeter Maydell 
1045aeb3689SPeter Maydell     memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
1055aeb3689SPeter Maydell                           s, "armsse-cpuid", 0x1000);
1065aeb3689SPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
1075aeb3689SPeter Maydell }
1085aeb3689SPeter Maydell 
armsse_cpuid_class_init(ObjectClass * klass,const void * data)109*12d1a768SPhilippe Mathieu-Daudé static void armsse_cpuid_class_init(ObjectClass *klass, const void *data)
1105aeb3689SPeter Maydell {
1115aeb3689SPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
1125aeb3689SPeter Maydell 
1135aeb3689SPeter Maydell     /*
1145aeb3689SPeter Maydell      * This device has no guest-modifiable state and so it
1155aeb3689SPeter Maydell      * does not need a reset function or VMState.
1165aeb3689SPeter Maydell      */
1175aeb3689SPeter Maydell 
1184f67d30bSMarc-André Lureau     device_class_set_props(dc, armsse_cpuid_props);
1195aeb3689SPeter Maydell }
1205aeb3689SPeter Maydell 
1215aeb3689SPeter Maydell static const TypeInfo armsse_cpuid_info = {
1225aeb3689SPeter Maydell     .name = TYPE_ARMSSE_CPUID,
1235aeb3689SPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
1245aeb3689SPeter Maydell     .instance_size = sizeof(ARMSSECPUID),
1255aeb3689SPeter Maydell     .instance_init = armsse_cpuid_init,
1265aeb3689SPeter Maydell     .class_init = armsse_cpuid_class_init,
1275aeb3689SPeter Maydell };
1285aeb3689SPeter Maydell 
armsse_cpuid_register_types(void)1295aeb3689SPeter Maydell static void armsse_cpuid_register_types(void)
1305aeb3689SPeter Maydell {
1315aeb3689SPeter Maydell     type_register_static(&armsse_cpuid_info);
1325aeb3689SPeter Maydell }
1335aeb3689SPeter Maydell 
1345aeb3689SPeter Maydell type_init(armsse_cpuid_register_types);
135