4 * Copyright IBM, Corp. 2012
7 * Christian Borntraeger <borntraeger@de.ibm.com>
8 * Heinz Graalfs <graalfs@linux.vnet.ibm.com>
10 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
11 * option) any later version. See the COPYING file in the top-level directory.
21 /* Provide information about the configuration, CPUs and storage */
22 static void read_SCP_info(SCCB
*sccb
)
24 ReadInfo
*read_info
= (ReadInfo
*) sccb
;
27 while ((ram_size
>> (20 + shift
)) > 65535) {
30 read_info
->rnmax
= cpu_to_be16(ram_size
>> (20 + shift
));
31 read_info
->rnsize
= 1 << shift
;
32 sccb
->h
.response_code
= cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION
);
35 static void sclp_execute(SCCB
*sccb
, uint64_t code
)
38 case SCLP_CMDW_READ_SCP_INFO
:
39 case SCLP_CMDW_READ_SCP_INFO_FORCED
:
43 sccb
->h
.response_code
= cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND
);
48 int sclp_service_call(uint32_t sccb
, uint64_t code
)
53 hwaddr sccb_len
= sizeof(SCCB
);
55 /* first some basic checks on program checks */
56 if (cpu_physical_memory_is_io(sccb
)) {
60 if (sccb
& ~0x7ffffff8ul
) {
61 r
= -PGM_SPECIFICATION
;
66 * we want to work on a private copy of the sccb, to prevent guests
67 * from playing dirty tricks by modifying the memory content after
68 * the host has checked the values
70 cpu_physical_memory_read(sccb
, &work_sccb
, sccb_len
);
72 /* Valid sccb sizes */
73 if (be16_to_cpu(work_sccb
.h
.length
) < sizeof(SCCBHeader
) ||
74 be16_to_cpu(work_sccb
.h
.length
) > SCCB_SIZE
) {
75 r
= -PGM_SPECIFICATION
;
79 sclp_execute((SCCB
*)&work_sccb
, code
);
81 cpu_physical_memory_write(sccb
, &work_sccb
,
82 be16_to_cpu(work_sccb
.h
.length
));
84 sclp_service_interrupt(sccb
);
90 void sclp_service_interrupt(uint32_t sccb
)
92 s390_sclp_extint(sccb
& ~3);
95 /* qemu object creation and initialization functions */
97 static void s390_sclp_device_class_init(ObjectClass
*klass
, void *data
)
99 SysBusDeviceClass
*dc
= SYS_BUS_DEVICE_CLASS(klass
);
101 dc
->init
= s390_sclp_dev_init
;
104 static TypeInfo s390_sclp_device_info
= {
105 .name
= TYPE_DEVICE_S390_SCLP
,
106 .parent
= TYPE_SYS_BUS_DEVICE
,
107 .instance_size
= sizeof(S390SCLPDevice
),
108 .class_init
= s390_sclp_device_class_init
,
109 .class_size
= sizeof(S390SCLPDeviceClass
),
113 static void s390_sclp_register_types(void)
115 type_register_static(&s390_sclp_device_info
);
118 type_init(s390_sclp_register_types
)