16c9f99dfSJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */
24da93626SDavid Hildenbrand /*
34da93626SDavid Hildenbrand * Copyright (c) 2017 Red Hat Inc
44da93626SDavid Hildenbrand *
54da93626SDavid Hildenbrand * Authors:
64da93626SDavid Hildenbrand * David Hildenbrand <david@redhat.com>
74da93626SDavid Hildenbrand */
84da93626SDavid Hildenbrand #ifndef _ASMS390X_IRQ_H_
94da93626SDavid Hildenbrand #define _ASMS390X_IRQ_H_
104da93626SDavid Hildenbrand #include <asm/arch_def.h>
114da93626SDavid Hildenbrand
12df121a0cSJanosch Frank #define EXT_IRQ_EMERGENCY_SIG 0x1201
13df121a0cSJanosch Frank #define EXT_IRQ_EXTERNAL_CALL 0x1202
148ead801eSJanosch Frank #define EXT_IRQ_SERVICE_SIG 0x2401
158ead801eSJanosch Frank
162652cb00SClaudio Imbrenda union teid {
172652cb00SClaudio Imbrenda unsigned long val;
18c2c1663aSJanis Schoetterl-Glausch union {
19c2c1663aSJanis Schoetterl-Glausch /* common fields DAT exc & protection exc */
202652cb00SClaudio Imbrenda struct {
21c2c1663aSJanis Schoetterl-Glausch uint64_t addr : 52 - 0;
22c2c1663aSJanis Schoetterl-Glausch uint64_t acc_exc_fetch_store : 54 - 52;
23c2c1663aSJanis Schoetterl-Glausch uint64_t side_effect_acc : 55 - 54;
24c2c1663aSJanis Schoetterl-Glausch uint64_t /* reserved */ : 62 - 55;
25c2c1663aSJanis Schoetterl-Glausch uint64_t asce_id : 64 - 62;
26c2c1663aSJanis Schoetterl-Glausch };
27c2c1663aSJanis Schoetterl-Glausch /* DAT exc */
28c2c1663aSJanis Schoetterl-Glausch struct {
29c2c1663aSJanis Schoetterl-Glausch uint64_t /* pad */ : 61 - 0;
30c2c1663aSJanis Schoetterl-Glausch uint64_t dat_move_page : 62 - 61;
31c2c1663aSJanis Schoetterl-Glausch };
32c2c1663aSJanis Schoetterl-Glausch /* suppression on protection */
33c2c1663aSJanis Schoetterl-Glausch struct {
34c2c1663aSJanis Schoetterl-Glausch uint64_t /* pad */ : 60 - 0;
35c2c1663aSJanis Schoetterl-Glausch uint64_t sop_acc_list : 61 - 60;
36c2c1663aSJanis Schoetterl-Glausch uint64_t sop_teid_predictable : 62 - 61;
37c2c1663aSJanis Schoetterl-Glausch };
38c2c1663aSJanis Schoetterl-Glausch /* enhanced suppression on protection 2 */
39c2c1663aSJanis Schoetterl-Glausch struct {
40c2c1663aSJanis Schoetterl-Glausch uint64_t /* pad */ : 56 - 0;
41c2c1663aSJanis Schoetterl-Glausch uint64_t esop2_prot_code_0 : 57 - 56;
42c2c1663aSJanis Schoetterl-Glausch uint64_t /* pad */ : 60 - 57;
43c2c1663aSJanis Schoetterl-Glausch uint64_t esop2_prot_code_1 : 61 - 60;
44c2c1663aSJanis Schoetterl-Glausch uint64_t esop2_prot_code_2 : 62 - 61;
452652cb00SClaudio Imbrenda };
462652cb00SClaudio Imbrenda };
47c2c1663aSJanis Schoetterl-Glausch };
48c2c1663aSJanis Schoetterl-Glausch
49c2c1663aSJanis Schoetterl-Glausch enum prot_code {
50c2c1663aSJanis Schoetterl-Glausch PROT_KEY_OR_LAP,
51c2c1663aSJanis Schoetterl-Glausch PROT_DAT,
52c2c1663aSJanis Schoetterl-Glausch PROT_KEY,
53c2c1663aSJanis Schoetterl-Glausch PROT_ACC_LIST,
54c2c1663aSJanis Schoetterl-Glausch PROT_LAP,
55c2c1663aSJanis Schoetterl-Glausch PROT_IEP,
56c2c1663aSJanis Schoetterl-Glausch PROT_NUM_CODES /* Must always be last */
57c2c1663aSJanis Schoetterl-Glausch };
58c2c1663aSJanis Schoetterl-Glausch
teid_esop2_prot_code(union teid teid)59c2c1663aSJanis Schoetterl-Glausch static inline enum prot_code teid_esop2_prot_code(union teid teid)
60c2c1663aSJanis Schoetterl-Glausch {
61c2c1663aSJanis Schoetterl-Glausch int code = (teid.esop2_prot_code_0 << 2 |
62c2c1663aSJanis Schoetterl-Glausch teid.esop2_prot_code_1 << 1 |
63c2c1663aSJanis Schoetterl-Glausch teid.esop2_prot_code_2);
64c2c1663aSJanis Schoetterl-Glausch
65c2c1663aSJanis Schoetterl-Glausch assert(code < PROT_NUM_CODES);
66c2c1663aSJanis Schoetterl-Glausch return (enum prot_code)code;
67c2c1663aSJanis Schoetterl-Glausch }
682652cb00SClaudio Imbrenda
694e5dd758SClaudio Imbrenda void register_pgm_cleanup_func(void (*f)(struct stack_frame_int *));
704e5dd758SClaudio Imbrenda void register_ext_cleanup_func(void (*f)(struct stack_frame_int *));
7136cfc0b7SJanosch Frank void handle_pgm_int(struct stack_frame_int *stack);
7236cfc0b7SJanosch Frank void handle_ext_int(struct stack_frame_int *stack);
730f87a91aSJanosch Frank void handle_mcck_int(void);
740f87a91aSJanosch Frank void handle_io_int(void);
750f87a91aSJanosch Frank void handle_svc_int(void);
764da93626SDavid Hildenbrand void expect_pgm_int(void);
77df121a0cSJanosch Frank void expect_ext_int(void);
783db880b6SDavid Hildenbrand uint16_t clear_pgm_int(void);
794da93626SDavid Hildenbrand void check_pgm_int_code(uint16_t code);
804da93626SDavid Hildenbrand
81fedfd112SNico Boehr void irq_set_dat_mode(bool use_dat, enum address_space as);
82fedfd112SNico Boehr
832667b05eSThomas Huth /* Activate low-address protection */
low_prot_enable(void)842667b05eSThomas Huth static inline void low_prot_enable(void)
852667b05eSThomas Huth {
861b2c0437SClaudio Imbrenda ctl_set_bit(0, CTL0_LOW_ADDR_PROT);
872667b05eSThomas Huth }
882667b05eSThomas Huth
892667b05eSThomas Huth /* Disable low-address protection */
low_prot_disable(void)902667b05eSThomas Huth static inline void low_prot_disable(void)
912667b05eSThomas Huth {
921b2c0437SClaudio Imbrenda ctl_clear_bit(0, CTL0_LOW_ADDR_PROT);
932667b05eSThomas Huth }
942667b05eSThomas Huth
95*54674baeSNico Boehr /**
96*54674baeSNico Boehr * read_pgm_int_code - Get the program interruption code of the last pgm int
97*54674baeSNico Boehr * on the current CPU.
98*54674baeSNico Boehr *
99*54674baeSNico Boehr * This is similar to clear_pgm_int(), except that it doesn't clear the
100*54674baeSNico Boehr * interruption information from lowcore.
101*54674baeSNico Boehr *
102*54674baeSNico Boehr * Return: 0 when none occurred.
103*54674baeSNico Boehr */
read_pgm_int_code(void)104*54674baeSNico Boehr static inline uint16_t read_pgm_int_code(void)
105*54674baeSNico Boehr {
106*54674baeSNico Boehr return lowcore.pgm_int_code;
107*54674baeSNico Boehr }
108*54674baeSNico Boehr
1094da93626SDavid Hildenbrand #endif
110