1*3994215dSYongbok Kim /* 2*3994215dSYongbok Kim * This file is subject to the terms and conditions of the GNU General Public 3*3994215dSYongbok Kim * License. See the file "COPYING" in the main directory of this archive 4*3994215dSYongbok Kim * for more details. 5*3994215dSYongbok Kim * 6*3994215dSYongbok Kim * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 7*3994215dSYongbok Kim * Authors: Sanjay Lal <sanjayl@kymasys.com> 8*3994215dSYongbok Kim * 9*3994215dSYongbok Kim * Copyright (C) 2015 Imagination Technologies 10*3994215dSYongbok Kim */ 11*3994215dSYongbok Kim 12*3994215dSYongbok Kim #include "qemu/osdep.h" 13*3994215dSYongbok Kim #include "qapi/error.h" 14*3994215dSYongbok Kim #include "hw/hw.h" 15*3994215dSYongbok Kim #include "hw/sysbus.h" 16*3994215dSYongbok Kim #include "sysemu/sysemu.h" 17*3994215dSYongbok Kim #include "hw/misc/mips_cmgcr.h" 18*3994215dSYongbok Kim 19*3994215dSYongbok Kim /* Read GCR registers */ 20*3994215dSYongbok Kim static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) 21*3994215dSYongbok Kim { 22*3994215dSYongbok Kim MIPSGCRState *gcr = (MIPSGCRState *) opaque; 23*3994215dSYongbok Kim 24*3994215dSYongbok Kim switch (addr) { 25*3994215dSYongbok Kim /* Global Control Block Register */ 26*3994215dSYongbok Kim case GCR_CONFIG_OFS: 27*3994215dSYongbok Kim /* Set PCORES to 0 */ 28*3994215dSYongbok Kim return 0; 29*3994215dSYongbok Kim case GCR_BASE_OFS: 30*3994215dSYongbok Kim return gcr->gcr_base; 31*3994215dSYongbok Kim case GCR_REV_OFS: 32*3994215dSYongbok Kim return gcr->gcr_rev; 33*3994215dSYongbok Kim case GCR_L2_CONFIG_OFS: 34*3994215dSYongbok Kim /* L2 BYPASS */ 35*3994215dSYongbok Kim return GCR_L2_CONFIG_BYPASS_MSK; 36*3994215dSYongbok Kim /* Core-Local and Core-Other Control Blocks */ 37*3994215dSYongbok Kim case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS: 38*3994215dSYongbok Kim case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: 39*3994215dSYongbok Kim /* Set PVP to # of VPs - 1 */ 40*3994215dSYongbok Kim return gcr->num_vps - 1; 41*3994215dSYongbok Kim case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: 42*3994215dSYongbok Kim return 0; 43*3994215dSYongbok Kim default: 44*3994215dSYongbok Kim qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx 45*3994215dSYongbok Kim "\n", size, addr); 46*3994215dSYongbok Kim return 0; 47*3994215dSYongbok Kim } 48*3994215dSYongbok Kim return 0; 49*3994215dSYongbok Kim } 50*3994215dSYongbok Kim 51*3994215dSYongbok Kim /* Write GCR registers */ 52*3994215dSYongbok Kim static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) 53*3994215dSYongbok Kim { 54*3994215dSYongbok Kim switch (addr) { 55*3994215dSYongbok Kim default: 56*3994215dSYongbok Kim qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx 57*3994215dSYongbok Kim " 0x%" PRIx64 "\n", size, addr, data); 58*3994215dSYongbok Kim break; 59*3994215dSYongbok Kim } 60*3994215dSYongbok Kim } 61*3994215dSYongbok Kim 62*3994215dSYongbok Kim static const MemoryRegionOps gcr_ops = { 63*3994215dSYongbok Kim .read = gcr_read, 64*3994215dSYongbok Kim .write = gcr_write, 65*3994215dSYongbok Kim .endianness = DEVICE_NATIVE_ENDIAN, 66*3994215dSYongbok Kim .impl = { 67*3994215dSYongbok Kim .max_access_size = 8, 68*3994215dSYongbok Kim }, 69*3994215dSYongbok Kim }; 70*3994215dSYongbok Kim 71*3994215dSYongbok Kim static void mips_gcr_init(Object *obj) 72*3994215dSYongbok Kim { 73*3994215dSYongbok Kim SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 74*3994215dSYongbok Kim MIPSGCRState *s = MIPS_GCR(obj); 75*3994215dSYongbok Kim 76*3994215dSYongbok Kim memory_region_init_io(&s->iomem, OBJECT(s), &gcr_ops, s, 77*3994215dSYongbok Kim "mips-gcr", GCR_ADDRSPACE_SZ); 78*3994215dSYongbok Kim sysbus_init_mmio(sbd, &s->iomem); 79*3994215dSYongbok Kim } 80*3994215dSYongbok Kim 81*3994215dSYongbok Kim static Property mips_gcr_properties[] = { 82*3994215dSYongbok Kim DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1), 83*3994215dSYongbok Kim DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800), 84*3994215dSYongbok Kim DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR), 85*3994215dSYongbok Kim DEFINE_PROP_END_OF_LIST(), 86*3994215dSYongbok Kim }; 87*3994215dSYongbok Kim 88*3994215dSYongbok Kim static void mips_gcr_class_init(ObjectClass *klass, void *data) 89*3994215dSYongbok Kim { 90*3994215dSYongbok Kim DeviceClass *dc = DEVICE_CLASS(klass); 91*3994215dSYongbok Kim dc->props = mips_gcr_properties; 92*3994215dSYongbok Kim } 93*3994215dSYongbok Kim 94*3994215dSYongbok Kim static const TypeInfo mips_gcr_info = { 95*3994215dSYongbok Kim .name = TYPE_MIPS_GCR, 96*3994215dSYongbok Kim .parent = TYPE_SYS_BUS_DEVICE, 97*3994215dSYongbok Kim .instance_size = sizeof(MIPSGCRState), 98*3994215dSYongbok Kim .instance_init = mips_gcr_init, 99*3994215dSYongbok Kim .class_init = mips_gcr_class_init, 100*3994215dSYongbok Kim }; 101*3994215dSYongbok Kim 102*3994215dSYongbok Kim static void mips_gcr_register_types(void) 103*3994215dSYongbok Kim { 104*3994215dSYongbok Kim type_register_static(&mips_gcr_info); 105*3994215dSYongbok Kim } 106*3994215dSYongbok Kim 107*3994215dSYongbok Kim type_init(mips_gcr_register_types) 108