xref: /kvm-unit-tests/lib/s390x/asm/interrupt.h (revision 54674bae100c6840171d9df5ba98721403a5493f)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2017 Red Hat Inc
4  *
5  * Authors:
6  *  David Hildenbrand <david@redhat.com>
7  */
8 #ifndef _ASMS390X_IRQ_H_
9 #define _ASMS390X_IRQ_H_
10 #include <asm/arch_def.h>
11 
12 #define EXT_IRQ_EMERGENCY_SIG	0x1201
13 #define EXT_IRQ_EXTERNAL_CALL	0x1202
14 #define EXT_IRQ_SERVICE_SIG	0x2401
15 
16 #define TEID_ASCE_PRIMARY	0
17 #define TEID_ASCE_AR		1
18 #define TEID_ASCE_SECONDARY	2
19 #define TEID_ASCE_HOME		3
20 
21 union teid {
22 	unsigned long val;
23 	union {
24 		/* common fields DAT exc & protection exc */
25 		struct {
26 			uint64_t addr			: 52 -  0;
27 			uint64_t acc_exc_fetch_store	: 54 - 52;
28 			uint64_t side_effect_acc	: 55 - 54;
29 			uint64_t /* reserved */		: 62 - 55;
30 			uint64_t asce_id		: 64 - 62;
31 		};
32 		/* DAT exc */
33 		struct {
34 			uint64_t /* pad */		: 61 -  0;
35 			uint64_t dat_move_page		: 62 - 61;
36 		};
37 		/* suppression on protection */
38 		struct {
39 			uint64_t /* pad */		: 60 -  0;
40 			uint64_t sop_acc_list		: 61 - 60;
41 			uint64_t sop_teid_predictable	: 62 - 61;
42 		};
43 		/* enhanced suppression on protection 2 */
44 		struct {
45 			uint64_t /* pad */		: 56 -  0;
46 			uint64_t esop2_prot_code_0	: 57 - 56;
47 			uint64_t /* pad */		: 60 - 57;
48 			uint64_t esop2_prot_code_1	: 61 - 60;
49 			uint64_t esop2_prot_code_2	: 62 - 61;
50 		};
51 	};
52 };
53 
54 enum prot_code {
55 	PROT_KEY_OR_LAP,
56 	PROT_DAT,
57 	PROT_KEY,
58 	PROT_ACC_LIST,
59 	PROT_LAP,
60 	PROT_IEP,
61 	PROT_NUM_CODES /* Must always be last */
62 };
63 
64 static inline enum prot_code teid_esop2_prot_code(union teid teid)
65 {
66 	int code = (teid.esop2_prot_code_0 << 2 |
67 		    teid.esop2_prot_code_1 << 1 |
68 		    teid.esop2_prot_code_2);
69 
70 	assert(code < PROT_NUM_CODES);
71 	return (enum prot_code)code;
72 }
73 
74 void register_pgm_cleanup_func(void (*f)(struct stack_frame_int *));
75 void register_ext_cleanup_func(void (*f)(struct stack_frame_int *));
76 void handle_pgm_int(struct stack_frame_int *stack);
77 void handle_ext_int(struct stack_frame_int *stack);
78 void handle_mcck_int(void);
79 void handle_io_int(void);
80 void handle_svc_int(void);
81 void expect_pgm_int(void);
82 void expect_ext_int(void);
83 uint16_t clear_pgm_int(void);
84 void check_pgm_int_code(uint16_t code);
85 
86 void irq_set_dat_mode(bool use_dat, enum address_space as);
87 
88 /* Activate low-address protection */
89 static inline void low_prot_enable(void)
90 {
91 	ctl_set_bit(0, CTL0_LOW_ADDR_PROT);
92 }
93 
94 /* Disable low-address protection */
95 static inline void low_prot_disable(void)
96 {
97 	ctl_clear_bit(0, CTL0_LOW_ADDR_PROT);
98 }
99 
100 /**
101  * read_pgm_int_code - Get the program interruption code of the last pgm int
102  * on the current CPU.
103  *
104  * This is similar to clear_pgm_int(), except that it doesn't clear the
105  * interruption information from lowcore.
106  *
107  * Return: 0 when none occurred.
108  */
109 static inline uint16_t read_pgm_int_code(void)
110 {
111 	return lowcore.pgm_int_code;
112 }
113 
114 #endif
115