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 union teid {
17 unsigned long val;
18 union {
19 /* common fields DAT exc & protection exc */
20 struct {
21 uint64_t addr : 52 - 0;
22 uint64_t acc_exc_fetch_store : 54 - 52;
23 uint64_t side_effect_acc : 55 - 54;
24 uint64_t /* reserved */ : 62 - 55;
25 uint64_t asce_id : 64 - 62;
26 };
27 /* DAT exc */
28 struct {
29 uint64_t /* pad */ : 61 - 0;
30 uint64_t dat_move_page : 62 - 61;
31 };
32 /* suppression on protection */
33 struct {
34 uint64_t /* pad */ : 60 - 0;
35 uint64_t sop_acc_list : 61 - 60;
36 uint64_t sop_teid_predictable : 62 - 61;
37 };
38 /* enhanced suppression on protection 2 */
39 struct {
40 uint64_t /* pad */ : 56 - 0;
41 uint64_t esop2_prot_code_0 : 57 - 56;
42 uint64_t /* pad */ : 60 - 57;
43 uint64_t esop2_prot_code_1 : 61 - 60;
44 uint64_t esop2_prot_code_2 : 62 - 61;
45 };
46 };
47 };
48
49 enum prot_code {
50 PROT_KEY_OR_LAP,
51 PROT_DAT,
52 PROT_KEY,
53 PROT_ACC_LIST,
54 PROT_LAP,
55 PROT_IEP,
56 PROT_NUM_CODES /* Must always be last */
57 };
58
teid_esop2_prot_code(union teid teid)59 static inline enum prot_code teid_esop2_prot_code(union teid teid)
60 {
61 int code = (teid.esop2_prot_code_0 << 2 |
62 teid.esop2_prot_code_1 << 1 |
63 teid.esop2_prot_code_2);
64
65 assert(code < PROT_NUM_CODES);
66 return (enum prot_code)code;
67 }
68
69 void register_pgm_cleanup_func(void (*f)(struct stack_frame_int *));
70 void register_ext_cleanup_func(void (*f)(struct stack_frame_int *));
71 void handle_pgm_int(struct stack_frame_int *stack);
72 void handle_ext_int(struct stack_frame_int *stack);
73 void handle_mcck_int(void);
74 void handle_io_int(void);
75 void handle_svc_int(void);
76 void expect_pgm_int(void);
77 void expect_ext_int(void);
78 uint16_t clear_pgm_int(void);
79 void check_pgm_int_code(uint16_t code);
80
81 void irq_set_dat_mode(bool use_dat, enum address_space as);
82
83 /* Activate low-address protection */
low_prot_enable(void)84 static inline void low_prot_enable(void)
85 {
86 ctl_set_bit(0, CTL0_LOW_ADDR_PROT);
87 }
88
89 /* Disable low-address protection */
low_prot_disable(void)90 static inline void low_prot_disable(void)
91 {
92 ctl_clear_bit(0, CTL0_LOW_ADDR_PROT);
93 }
94
95 /**
96 * read_pgm_int_code - Get the program interruption code of the last pgm int
97 * on the current CPU.
98 *
99 * This is similar to clear_pgm_int(), except that it doesn't clear the
100 * interruption information from lowcore.
101 *
102 * Return: 0 when none occurred.
103 */
read_pgm_int_code(void)104 static inline uint16_t read_pgm_int_code(void)
105 {
106 return lowcore.pgm_int_code;
107 }
108
109 #endif
110