xref: /kvm-unit-tests/lib/s390x/asm/uv.h (revision 88fb0e5d52be357d3aab854c5c16303fe1608335)
12ea7afb6SJanosch Frank /*
22ea7afb6SJanosch Frank  * s390x Ultravisor related definitions
32ea7afb6SJanosch Frank  *
42ea7afb6SJanosch Frank  * Copyright (c) 2020 IBM Corp
52ea7afb6SJanosch Frank  *
62ea7afb6SJanosch Frank  * Authors:
72ea7afb6SJanosch Frank  *  Janosch Frank <frankja@linux.ibm.com>
82ea7afb6SJanosch Frank  *
92ea7afb6SJanosch Frank  * This code is free software; you can redistribute it and/or modify it
102ea7afb6SJanosch Frank  * under the terms of the GNU General Public License version 2.
112ea7afb6SJanosch Frank  */
122ea7afb6SJanosch Frank #ifndef UV_H
132ea7afb6SJanosch Frank #define UV_H
142ea7afb6SJanosch Frank 
152ea7afb6SJanosch Frank #define UVC_RC_EXECUTED		0x0001
162ea7afb6SJanosch Frank #define UVC_RC_INV_CMD		0x0002
172ea7afb6SJanosch Frank #define UVC_RC_INV_STATE	0x0003
182ea7afb6SJanosch Frank #define UVC_RC_INV_LEN		0x0005
192ea7afb6SJanosch Frank #define UVC_RC_NO_RESUME	0x0007
202ea7afb6SJanosch Frank 
212ea7afb6SJanosch Frank #define UVC_CMD_QUI			0x0001
222ea7afb6SJanosch Frank #define UVC_CMD_SET_SHARED_ACCESS	0x1000
232ea7afb6SJanosch Frank #define UVC_CMD_REMOVE_SHARED_ACCESS	0x1001
242ea7afb6SJanosch Frank 
252ea7afb6SJanosch Frank /* Bits in installed uv calls */
262ea7afb6SJanosch Frank enum uv_cmds_inst {
272ea7afb6SJanosch Frank 	BIT_UVC_CMD_QUI = 0,
282ea7afb6SJanosch Frank 	BIT_UVC_CMD_SET_SHARED_ACCESS = 8,
292ea7afb6SJanosch Frank 	BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9,
302ea7afb6SJanosch Frank };
312ea7afb6SJanosch Frank 
322ea7afb6SJanosch Frank struct uv_cb_header {
332ea7afb6SJanosch Frank 	u16 len;
342ea7afb6SJanosch Frank 	u16 cmd;	/* Command Code */
352ea7afb6SJanosch Frank 	u16 rc;		/* Response Code */
362ea7afb6SJanosch Frank 	u16 rrc;	/* Return Reason Code */
372ea7afb6SJanosch Frank } __attribute__((packed))  __attribute__((aligned(8)));
382ea7afb6SJanosch Frank 
392ea7afb6SJanosch Frank struct uv_cb_qui {
402ea7afb6SJanosch Frank 	struct uv_cb_header header;
412ea7afb6SJanosch Frank 	u64 reserved08;
422ea7afb6SJanosch Frank 	u64 inst_calls_list[4];
432ea7afb6SJanosch Frank 	u64 reserved30[15];
442ea7afb6SJanosch Frank } __attribute__((packed))  __attribute__((aligned(8)));
452ea7afb6SJanosch Frank 
462ea7afb6SJanosch Frank struct uv_cb_share {
472ea7afb6SJanosch Frank 	struct uv_cb_header header;
482ea7afb6SJanosch Frank 	u64 reserved08[3];
492ea7afb6SJanosch Frank 	u64 paddr;
502ea7afb6SJanosch Frank 	u64 reserved28;
512ea7afb6SJanosch Frank } __attribute__((packed))  __attribute__((aligned(8)));
522ea7afb6SJanosch Frank 
53*88fb0e5dSJanosch Frank static inline int uv_call_once(unsigned long r1, unsigned long r2)
542ea7afb6SJanosch Frank {
552ea7afb6SJanosch Frank 	int cc;
562ea7afb6SJanosch Frank 
572ea7afb6SJanosch Frank 	asm volatile(
582ea7afb6SJanosch Frank 		"0:	.insn rrf,0xB9A40000,%[r1],%[r2],0,0\n"
592ea7afb6SJanosch Frank 		"		ipm	%[cc]\n"
602ea7afb6SJanosch Frank 		"		srl	%[cc],28\n"
612ea7afb6SJanosch Frank 		: [cc] "=d" (cc)
622ea7afb6SJanosch Frank 		: [r1] "a" (r1), [r2] "a" (r2)
632ea7afb6SJanosch Frank 		: "memory", "cc");
642ea7afb6SJanosch Frank 	return cc;
652ea7afb6SJanosch Frank }
662ea7afb6SJanosch Frank 
67*88fb0e5dSJanosch Frank static inline int uv_call(unsigned long r1, unsigned long r2)
68*88fb0e5dSJanosch Frank {
69*88fb0e5dSJanosch Frank 	int cc;
70*88fb0e5dSJanosch Frank 
71*88fb0e5dSJanosch Frank 	/*
72*88fb0e5dSJanosch Frank 	 * CC 2 and 3 tell us to re-execute because the instruction
73*88fb0e5dSJanosch Frank 	 * hasn't yet finished.
74*88fb0e5dSJanosch Frank 	 */
75*88fb0e5dSJanosch Frank 	do {
76*88fb0e5dSJanosch Frank 		cc = uv_call_once(r1, r2);
77*88fb0e5dSJanosch Frank 	} while (cc > 1);
78*88fb0e5dSJanosch Frank 
79*88fb0e5dSJanosch Frank 	return cc;
80*88fb0e5dSJanosch Frank }
81*88fb0e5dSJanosch Frank 
822ea7afb6SJanosch Frank #endif
83