2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 * Authors: Sanjay Lal <sanjayl@kymasys.com>
9 * Copyright (C) 2015 Imagination Technologies
12 #include "qemu/osdep.h"
13 #include "qapi/error.h"
16 #include "hw/sysbus.h"
17 #include "sysemu/sysemu.h"
18 #include "hw/misc/mips_cmgcr.h"
19 #include "hw/misc/mips_cpc.h"
21 static inline bool is_cpc_connected(MIPSGCRState
*s
)
23 return s
->cpc_mr
!= NULL
;
26 static inline void update_cpc_base(MIPSGCRState
*gcr
, uint64_t val
)
28 if (is_cpc_connected(gcr
)) {
29 gcr
->cpc_base
= val
& GCR_CPC_BASE_MSK
;
30 memory_region_transaction_begin();
31 memory_region_set_address(gcr
->cpc_mr
,
32 gcr
->cpc_base
& GCR_CPC_BASE_CPCBASE_MSK
);
33 memory_region_set_enabled(gcr
->cpc_mr
,
34 gcr
->cpc_base
& GCR_CPC_BASE_CPCEN_MSK
);
35 memory_region_transaction_commit();
39 /* Read GCR registers */
40 static uint64_t gcr_read(void *opaque
, hwaddr addr
, unsigned size
)
42 MIPSGCRState
*gcr
= (MIPSGCRState
*) opaque
;
45 /* Global Control Block Register */
53 case GCR_CPC_BASE_OFS
:
55 case GCR_CPC_STATUS_OFS
:
56 return is_cpc_connected(gcr
);
57 case GCR_L2_CONFIG_OFS
:
59 return GCR_L2_CONFIG_BYPASS_MSK
;
60 /* Core-Local and Core-Other Control Blocks */
61 case MIPS_CLCB_OFS
+ GCR_CL_CONFIG_OFS
:
62 case MIPS_COCB_OFS
+ GCR_CL_CONFIG_OFS
:
63 /* Set PVP to # of VPs - 1 */
64 return gcr
->num_vps
- 1;
65 case MIPS_CLCB_OFS
+ GCR_CL_OTHER_OFS
:
68 qemu_log_mask(LOG_UNIMP
, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
75 /* Write GCR registers */
76 static void gcr_write(void *opaque
, hwaddr addr
, uint64_t data
, unsigned size
)
78 MIPSGCRState
*gcr
= (MIPSGCRState
*)opaque
;
81 case GCR_CPC_BASE_OFS
:
82 update_cpc_base(gcr
, data
);
85 qemu_log_mask(LOG_UNIMP
, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx
86 " 0x%" PRIx64
"\n", size
, addr
, data
);
91 static const MemoryRegionOps gcr_ops
= {
94 .endianness
= DEVICE_NATIVE_ENDIAN
,
100 static void mips_gcr_init(Object
*obj
)
102 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
103 MIPSGCRState
*s
= MIPS_GCR(obj
);
105 object_property_add_link(obj
, "cpc", TYPE_MEMORY_REGION
,
106 (Object
**)&s
->cpc_mr
,
107 qdev_prop_allow_set_link_before_realize
,
108 OBJ_PROP_LINK_UNREF_ON_RELEASE
,
111 memory_region_init_io(&s
->iomem
, OBJECT(s
), &gcr_ops
, s
,
112 "mips-gcr", GCR_ADDRSPACE_SZ
);
113 sysbus_init_mmio(sbd
, &s
->iomem
);
116 static void mips_gcr_reset(DeviceState
*dev
)
118 MIPSGCRState
*s
= MIPS_GCR(dev
);
120 update_cpc_base(s
, 0);
123 static const VMStateDescription vmstate_mips_gcr
= {
126 .minimum_version_id
= 0,
127 .fields
= (VMStateField
[]) {
128 VMSTATE_UINT64(cpc_base
, MIPSGCRState
),
129 VMSTATE_END_OF_LIST()
133 static Property mips_gcr_properties
[] = {
134 DEFINE_PROP_INT32("num-vp", MIPSGCRState
, num_vps
, 1),
135 DEFINE_PROP_INT32("gcr-rev", MIPSGCRState
, gcr_rev
, 0x800),
136 DEFINE_PROP_UINT64("gcr-base", MIPSGCRState
, gcr_base
, GCR_BASE_ADDR
),
137 DEFINE_PROP_END_OF_LIST(),
140 static void mips_gcr_class_init(ObjectClass
*klass
, void *data
)
142 DeviceClass
*dc
= DEVICE_CLASS(klass
);
143 dc
->props
= mips_gcr_properties
;
144 dc
->vmsd
= &vmstate_mips_gcr
;
145 dc
->reset
= mips_gcr_reset
;
148 static const TypeInfo mips_gcr_info
= {
149 .name
= TYPE_MIPS_GCR
,
150 .parent
= TYPE_SYS_BUS_DEVICE
,
151 .instance_size
= sizeof(MIPSGCRState
),
152 .instance_init
= mips_gcr_init
,
153 .class_init
= mips_gcr_class_init
,
156 static void mips_gcr_register_types(void)
158 type_register_static(&mips_gcr_info
);
161 type_init(mips_gcr_register_types
)