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