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 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 */ 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 */ 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 */ 104 static inline uint16_t read_pgm_int_code(void) 105 { 106 return lowcore.pgm_int_code; 107 } 108 109 #endif 110