@@ -309,6 +309,7 @@ struct chsc_scsc {
uint8_t reserved[9];
struct chsc_header res;
uint32_t res_fmt;
+#define CSSC_EXTENDED_MEASUREMENT_BLOCK 48
uint64_t general_char[255];
uint64_t chsc_char[254];
};
@@ -359,6 +360,17 @@ bool chsc(void *p, uint16_t code, uint16_t len);
#define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char)
#define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char)
+#define SCHM_DCTM 1 /* activate Device Connection TiMe */
+#define SCHM_MBU 2 /* activate Measurement Block Update */
+
+static inline void schm(void *mbo, unsigned int flags)
+{
+ register void *__gpr2 asm("2") = mbo;
+ register long __gpr1 asm("1") = flags;
+
+ asm("schm" : : "d" (__gpr2), "d" (__gpr1));
+}
+
bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1);
bool css_disable_mb(int schid);
@@ -141,6 +141,40 @@ static void css_init(void)
report(get_chsc_scsc(), "Store Channel Characteristics");
}
+static void test_schm(void)
+{
+ if (css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK))
+ report_info("Extended measurement block available");
+
+ /* bits 59-63 of MB address must be 0 if MBU is defined */
+ report_prefix_push("Unaligned operand");
+ expect_pgm_int();
+ schm((void *)0x01, SCHM_MBU);
+ check_pgm_int_code(PGM_INT_CODE_OPERAND);
+ report_prefix_pop();
+
+ /* bits 36-61 of register 1 (flags) must be 0 */
+ report_prefix_push("Bad flags");
+ expect_pgm_int();
+ schm(NULL, 0xfffffffc);
+ check_pgm_int_code(PGM_INT_CODE_OPERAND);
+ report_prefix_pop();
+
+ /* SCHM is a privilege operation */
+ report_prefix_push("Privilege");
+ enter_pstate();
+ expect_pgm_int();
+ schm(NULL, SCHM_MBU);
+ check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
+ report_prefix_pop();
+
+ /* Normal operation */
+ report_prefix_push("Normal operation");
+ schm(NULL, SCHM_MBU);
+ report(1, "SCHM call without address");
+ report_prefix_pop();
+}
+
static struct {
const char *name;
void (*func)(void);
@@ -150,6 +184,7 @@ static struct {
{ "enumerate (stsch)", test_enumerate },
{ "enable (msch)", test_enable },
{ "sense (ssch/tsch)", test_sense },
+ { "measurement block (schm)", test_schm },
{ NULL, NULL }
};