Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright IBM Corp. 1999,2012
0004  *
0005  * Author(s): Martin Peschke <mpeschke@de.ibm.com>
0006  *        Martin Schwidefsky <schwidefsky@de.ibm.com>
0007  */
0008 
0009 #ifndef __SCLP_H__
0010 #define __SCLP_H__
0011 
0012 #include <linux/types.h>
0013 #include <linux/list.h>
0014 #include <asm/asm-extable.h>
0015 #include <asm/sclp.h>
0016 #include <asm/ebcdic.h>
0017 
0018 /* maximum number of pages concerning our own memory management */
0019 #define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
0020 #define SCLP_CONSOLE_PAGES  6
0021 
0022 #define SCLP_EVTYP_MASK(T) (1UL << (sizeof(sccb_mask_t) * BITS_PER_BYTE - (T)))
0023 
0024 #define EVTYP_OPCMD     0x01
0025 #define EVTYP_MSG       0x02
0026 #define EVTYP_CONFMGMDATA   0x04
0027 #define EVTYP_DIAG_TEST     0x07
0028 #define EVTYP_STATECHANGE   0x08
0029 #define EVTYP_PMSGCMD       0x09
0030 #define EVTYP_ASYNC     0x0A
0031 #define EVTYP_CTLPROGIDENT  0x0B
0032 #define EVTYP_STORE_DATA    0x0C
0033 #define EVTYP_ERRNOTIFY     0x18
0034 #define EVTYP_VT220MSG      0x1A
0035 #define EVTYP_SDIAS     0x1C
0036 #define EVTYP_SIGQUIESCE    0x1D
0037 #define EVTYP_OCF       0x1E
0038 
0039 #define EVTYP_OPCMD_MASK    SCLP_EVTYP_MASK(EVTYP_OPCMD)
0040 #define EVTYP_MSG_MASK      SCLP_EVTYP_MASK(EVTYP_MSG)
0041 #define EVTYP_CONFMGMDATA_MASK  SCLP_EVTYP_MASK(EVTYP_CONFMGMDATA)
0042 #define EVTYP_DIAG_TEST_MASK    SCLP_EVTYP_MASK(EVTYP_DIAG_TEST)
0043 #define EVTYP_STATECHANGE_MASK  SCLP_EVTYP_MASK(EVTYP_STATECHANGE)
0044 #define EVTYP_PMSGCMD_MASK  SCLP_EVTYP_MASK(EVTYP_PMSGCMD)
0045 #define EVTYP_ASYNC_MASK    SCLP_EVTYP_MASK(EVTYP_ASYNC)
0046 #define EVTYP_CTLPROGIDENT_MASK SCLP_EVTYP_MASK(EVTYP_CTLPROGIDENT)
0047 #define EVTYP_STORE_DATA_MASK   SCLP_EVTYP_MASK(EVTYP_STORE_DATA)
0048 #define EVTYP_ERRNOTIFY_MASK    SCLP_EVTYP_MASK(EVTYP_ERRNOTIFY)
0049 #define EVTYP_VT220MSG_MASK SCLP_EVTYP_MASK(EVTYP_VT220MSG)
0050 #define EVTYP_SDIAS_MASK    SCLP_EVTYP_MASK(EVTYP_SDIAS)
0051 #define EVTYP_SIGQUIESCE_MASK   SCLP_EVTYP_MASK(EVTYP_SIGQUIESCE)
0052 #define EVTYP_OCF_MASK      SCLP_EVTYP_MASK(EVTYP_OCF)
0053 
0054 #define GNRLMSGFLGS_DOM     0x8000
0055 #define GNRLMSGFLGS_SNDALRM 0x4000
0056 #define GNRLMSGFLGS_HOLDMSG 0x2000
0057 
0058 #define LNTPFLGS_CNTLTEXT   0x8000
0059 #define LNTPFLGS_LABELTEXT  0x4000
0060 #define LNTPFLGS_DATATEXT   0x2000
0061 #define LNTPFLGS_ENDTEXT    0x1000
0062 #define LNTPFLGS_PROMPTTEXT 0x0800
0063 
0064 typedef unsigned int sclp_cmdw_t;
0065 
0066 #define SCLP_CMDW_READ_CPU_INFO     0x00010001
0067 #define SCLP_CMDW_READ_SCP_INFO     0x00020001
0068 #define SCLP_CMDW_READ_STORAGE_INFO 0x00040001
0069 #define SCLP_CMDW_READ_SCP_INFO_FORCED  0x00120001
0070 #define SCLP_CMDW_READ_EVENT_DATA   0x00770005
0071 #define SCLP_CMDW_WRITE_EVENT_DATA  0x00760005
0072 #define SCLP_CMDW_WRITE_EVENT_MASK  0x00780005
0073 
0074 #define GDS_ID_MDSMU        0x1310
0075 #define GDS_ID_MDSROUTEINFO 0x1311
0076 #define GDS_ID_AGUNWRKCORR  0x1549
0077 #define GDS_ID_SNACONDREPORT    0x1532
0078 #define GDS_ID_CPMSU        0x1212
0079 #define GDS_ID_ROUTTARGINSTR    0x154D
0080 #define GDS_ID_OPREQ        0x8070
0081 #define GDS_ID_TEXTCMD      0x1320
0082 
0083 #define GDS_KEY_SELFDEFTEXTMSG  0x31
0084 
0085 typedef u64 sccb_mask_t;
0086 
0087 struct sccb_header {
0088     u16 length;
0089     u8  function_code;
0090     u8  control_mask[3];
0091     u16 response_code;
0092 } __attribute__((packed));
0093 
0094 struct init_sccb {
0095     struct sccb_header header;
0096     u16 _reserved;
0097     u16 mask_length;
0098     u8 masks[4 * 1021]; /* variable length */
0099     /*
0100      * u8 receive_mask[mask_length];
0101      * u8 send_mask[mask_length];
0102      * u8 sclp_receive_mask[mask_length];
0103      * u8 sclp_send_mask[mask_length];
0104      */
0105 } __attribute__((packed));
0106 
0107 #define SCLP_MASK_SIZE_COMPAT 4
0108 
0109 static inline sccb_mask_t sccb_get_mask(u8 *masks, size_t len, int i)
0110 {
0111     sccb_mask_t res = 0;
0112 
0113     memcpy(&res, masks + i * len, min(sizeof(res), len));
0114     return res;
0115 }
0116 
0117 static inline void sccb_set_mask(u8 *masks, size_t len, int i, sccb_mask_t val)
0118 {
0119     memset(masks + i * len, 0, len);
0120     memcpy(masks + i * len, &val, min(sizeof(val), len));
0121 }
0122 
0123 #define sccb_get_generic_mask(sccb, i)                  \
0124 ({                                  \
0125     __typeof__(sccb) __sccb = sccb;                 \
0126                                     \
0127     sccb_get_mask(__sccb->masks, __sccb->mask_length, i);       \
0128 })
0129 #define sccb_get_recv_mask(sccb)    sccb_get_generic_mask(sccb, 0)
0130 #define sccb_get_send_mask(sccb)    sccb_get_generic_mask(sccb, 1)
0131 #define sccb_get_sclp_recv_mask(sccb)   sccb_get_generic_mask(sccb, 2)
0132 #define sccb_get_sclp_send_mask(sccb)   sccb_get_generic_mask(sccb, 3)
0133 
0134 #define sccb_set_generic_mask(sccb, i, val)             \
0135 ({                                  \
0136     __typeof__(sccb) __sccb = sccb;                 \
0137                                     \
0138     sccb_set_mask(__sccb->masks, __sccb->mask_length, i, val);  \
0139 })
0140 #define sccb_set_recv_mask(sccb, val)       sccb_set_generic_mask(sccb, 0, val)
0141 #define sccb_set_send_mask(sccb, val)       sccb_set_generic_mask(sccb, 1, val)
0142 #define sccb_set_sclp_recv_mask(sccb, val)  sccb_set_generic_mask(sccb, 2, val)
0143 #define sccb_set_sclp_send_mask(sccb, val)  sccb_set_generic_mask(sccb, 3, val)
0144 
0145 struct read_cpu_info_sccb {
0146     struct  sccb_header header;
0147     u16 nr_configured;
0148     u16 offset_configured;
0149     u16 nr_standby;
0150     u16 offset_standby;
0151     /*
0152      * Without ext sccb, struct size is PAGE_SIZE.
0153      * With ext sccb, struct size is EXT_SCCB_READ_CPU.
0154      */
0155     u8  reserved[];
0156 } __attribute__((packed, aligned(PAGE_SIZE)));
0157 
0158 struct read_info_sccb {
0159     struct  sccb_header header; /* 0-7 */
0160     u16 rnmax;          /* 8-9 */
0161     u8  rnsize;         /* 10 */
0162     u8  _pad_11[16 - 11];   /* 11-15 */
0163     u16 ncpurl;         /* 16-17 */
0164     u16 cpuoff;         /* 18-19 */
0165     u8  _pad_20[24 - 20];   /* 20-23 */
0166     u8  loadparm[8];        /* 24-31 */
0167     u8  _pad_32[42 - 32];   /* 32-41 */
0168     u8  fac42;          /* 42 */
0169     u8  fac43;          /* 43 */
0170     u8  _pad_44[48 - 44];   /* 44-47 */
0171     u64 facilities;     /* 48-55 */
0172     u8  _pad_56[66 - 56];   /* 56-65 */
0173     u8  fac66;          /* 66 */
0174     u8  _pad_67[76 - 67];   /* 67-83 */
0175     u32 ibc;            /* 76-79 */
0176     u8  _pad80[84 - 80];    /* 80-83 */
0177     u8  fac84;          /* 84 */
0178     u8  fac85;          /* 85 */
0179     u8  _pad_86[91 - 86];   /* 86-90 */
0180     u8  fac91;          /* 91 */
0181     u8  _pad_92[98 - 92];   /* 92-97 */
0182     u8  fac98;          /* 98 */
0183     u8  hamaxpow;       /* 99 */
0184     u32 rnsize2;        /* 100-103 */
0185     u64 rnmax2;         /* 104-111 */
0186     u32 hsa_size;       /* 112-115 */
0187     u8  fac116;         /* 116 */
0188     u8  fac117;         /* 117 */
0189     u8  fac118;         /* 118 */
0190     u8  fac119;         /* 119 */
0191     u16 hcpua;          /* 120-121 */
0192     u8  _pad_122[124 - 122];    /* 122-123 */
0193     u32 hmfai;          /* 124-127 */
0194     u8  _pad_128[134 - 128];    /* 128-133 */
0195     u8  byte_134;           /* 134 */
0196     u8  cpudirq;        /* 135 */
0197     u16 cbl;            /* 136-137 */
0198     u8  _pad_138[EXT_SCCB_READ_SCP - 138];
0199 } __packed __aligned(PAGE_SIZE);
0200 
0201 struct read_storage_sccb {
0202     struct sccb_header header;
0203     u16 max_id;
0204     u16 assigned;
0205     u16 standby;
0206     u16 :16;
0207     u32 entries[0];
0208 } __packed;
0209 
0210 static inline void sclp_fill_core_info(struct sclp_core_info *info,
0211                        struct read_cpu_info_sccb *sccb)
0212 {
0213     char *page = (char *) sccb;
0214 
0215     memset(info, 0, sizeof(*info));
0216     info->configured = sccb->nr_configured;
0217     info->standby = sccb->nr_standby;
0218     info->combined = sccb->nr_configured + sccb->nr_standby;
0219     memcpy(&info->core, page + sccb->offset_configured,
0220            info->combined * sizeof(struct sclp_core_entry));
0221 }
0222 
0223 #define SCLP_HAS_CHP_INFO   (sclp.facilities & 0x8000000000000000ULL)
0224 #define SCLP_HAS_CHP_RECONFIG   (sclp.facilities & 0x2000000000000000ULL)
0225 #define SCLP_HAS_CPU_INFO   (sclp.facilities & 0x0800000000000000ULL)
0226 #define SCLP_HAS_CPU_RECONFIG   (sclp.facilities & 0x0400000000000000ULL)
0227 #define SCLP_HAS_PCI_RECONFIG   (sclp.facilities & 0x0000000040000000ULL)
0228 #define SCLP_HAS_AP_RECONFIG    (sclp.facilities & 0x0000000100000000ULL)
0229 
0230 struct gds_subvector {
0231     u8  length;
0232     u8  key;
0233 } __attribute__((packed));
0234 
0235 struct gds_vector {
0236     u16 length;
0237     u16 gds_id;
0238 } __attribute__((packed));
0239 
0240 struct evbuf_header {
0241     u16 length;
0242     u8  type;
0243     u8  flags;
0244     u16 _reserved;
0245 } __attribute__((packed));
0246 
0247 struct sclp_req {
0248     struct list_head list;      /* list_head for request queueing. */
0249     sclp_cmdw_t command;        /* sclp command to execute */
0250     void    *sccb;          /* pointer to the sccb to execute */
0251     char    status;         /* status of this request */
0252     int     start_count;        /* number of SVCs done for this req */
0253     /* Callback that is called after reaching final status. */
0254     void (*callback)(struct sclp_req *, void *data);
0255     void *callback_data;
0256     int queue_timeout;      /* request queue timeout (sec), set by
0257                        caller of sclp_add_request(), if
0258                        needed */
0259     /* Internal fields */
0260     unsigned long queue_expires;    /* request queue timeout (jiffies) */
0261 };
0262 
0263 #define SCLP_REQ_FILLED   0x00  /* request is ready to be processed */
0264 #define SCLP_REQ_QUEUED   0x01  /* request is queued to be processed */
0265 #define SCLP_REQ_RUNNING  0x02  /* request is currently running */
0266 #define SCLP_REQ_DONE     0x03  /* request is completed successfully */
0267 #define SCLP_REQ_FAILED   0x05  /* request is finally failed */
0268 #define SCLP_REQ_QUEUED_TIMEOUT 0x06    /* request on queue timed out */
0269 
0270 #define SCLP_QUEUE_INTERVAL 5   /* timeout interval for request queue */
0271 
0272 /* function pointers that a high level driver has to use for registration */
0273 /* of some routines it wants to be called from the low level driver */
0274 struct sclp_register {
0275     struct list_head list;
0276     /* User wants to receive: */
0277     sccb_mask_t receive_mask;
0278     /* User wants to send: */
0279     sccb_mask_t send_mask;
0280     /* H/W can receive: */
0281     sccb_mask_t sclp_receive_mask;
0282     /* H/W can send: */
0283     sccb_mask_t sclp_send_mask;
0284     /* called if event type availability changes */
0285     void (*state_change_fn)(struct sclp_register *);
0286     /* called for events in cp_receive_mask/sclp_receive_mask */
0287     void (*receiver_fn)(struct evbuf_header *);
0288 };
0289 
0290 /* externals from sclp.c */
0291 int sclp_add_request(struct sclp_req *req);
0292 void sclp_sync_wait(void);
0293 int sclp_register(struct sclp_register *reg);
0294 void sclp_unregister(struct sclp_register *reg);
0295 int sclp_remove_processed(struct sccb_header *sccb);
0296 int sclp_deactivate(void);
0297 int sclp_reactivate(void);
0298 int sclp_sync_request(sclp_cmdw_t command, void *sccb);
0299 int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout);
0300 int sclp_sdias_init(void);
0301 
0302 enum {
0303     sclp_init_state_uninitialized,
0304     sclp_init_state_initializing,
0305     sclp_init_state_initialized
0306 };
0307 
0308 extern int sclp_init_state;
0309 extern int sclp_console_pages;
0310 extern int sclp_console_drop;
0311 extern unsigned long sclp_console_full;
0312 extern bool sclp_mask_compat_mode;
0313 
0314 void sclp_early_wait_irq(void);
0315 int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
0316 unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
0317 unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb);
0318 int sclp_early_set_event_mask(struct init_sccb *sccb,
0319                   sccb_mask_t receive_mask,
0320                   sccb_mask_t send_mask);
0321 struct read_info_sccb * __init sclp_early_get_info(void);
0322 
0323 /* useful inlines */
0324 
0325 /* Perform service call. Return 0 on success, non-zero otherwise. */
0326 static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
0327 {
0328     int cc = 4; /* Initialize for program check handling */
0329 
0330     asm volatile(
0331         "0: .insn   rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
0332         "1: ipm %0\n"
0333         "   srl %0,28\n"
0334         "2:\n"
0335         EX_TABLE(0b, 2b)
0336         EX_TABLE(1b, 2b)
0337         : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
0338         : "cc", "memory");
0339     if (cc == 4)
0340         return -EINVAL;
0341     if (cc == 3)
0342         return -EIO;
0343     if (cc == 2)
0344         return -EBUSY;
0345     return 0;
0346 }
0347 
0348 /* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
0349 /* translate single character from ASCII to EBCDIC */
0350 static inline unsigned char
0351 sclp_ascebc(unsigned char ch)
0352 {
0353     return (MACHINE_IS_VM) ? _ascebc[ch] : _ascebc_500[ch];
0354 }
0355 
0356 /* translate string from EBCDIC to ASCII */
0357 static inline void
0358 sclp_ebcasc_str(char *str, int nr)
0359 {
0360     (MACHINE_IS_VM) ? EBCASC(str, nr) : EBCASC_500(str, nr);
0361 }
0362 
0363 /* translate string from ASCII to EBCDIC */
0364 static inline void
0365 sclp_ascebc_str(char *str, int nr)
0366 {
0367     (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
0368 }
0369 
0370 static inline struct gds_vector *
0371 sclp_find_gds_vector(void *start, void *end, u16 id)
0372 {
0373     struct gds_vector *v;
0374 
0375     for (v = start; (void *) v < end; v = (void *) v + v->length)
0376         if (v->gds_id == id)
0377             return v;
0378     return NULL;
0379 }
0380 
0381 static inline struct gds_subvector *
0382 sclp_find_gds_subvector(void *start, void *end, u8 key)
0383 {
0384     struct gds_subvector *sv;
0385 
0386     for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
0387         if (sv->key == key)
0388             return sv;
0389     return NULL;
0390 }
0391 
0392 #endif   /* __SCLP_H__ */