1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2e657d8feSMichael Holzheu /* 3e657d8feSMichael Holzheu * SCLP early driver 4e657d8feSMichael Holzheu * 5e657d8feSMichael Holzheu * Copyright IBM Corp. 2013 6e657d8feSMichael Holzheu */ 7e657d8feSMichael Holzheu 8e657d8feSMichael Holzheu #define KMSG_COMPONENT "sclp_early" 9e657d8feSMichael Holzheu #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10e657d8feSMichael Holzheu 11a313bdc5SSebastian Ott #include <linux/errno.h> 12acf6a004SMichael Holzheu #include <asm/ctl_reg.h> 13e657d8feSMichael Holzheu #include <asm/sclp.h> 14e657d8feSMichael Holzheu #include <asm/ipl.h> 15e657d8feSMichael Holzheu #include "sclp_sdias.h" 16e657d8feSMichael Holzheu #include "sclp.h" 17e657d8feSMichael Holzheu 18333cce91SHendrik Brueckner static struct sclp_ipl_info sclp_ipl_info; 19e657d8feSMichael Holzheu 2037c5f6c8SDavid Hildenbrand struct sclp_info sclp; 2137c5f6c8SDavid Hildenbrand EXPORT_SYMBOL(sclp); 22acf6a004SMichael Holzheu 23d5ab7a34SHeiko Carstens static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb) 24acf6a004SMichael Holzheu { 25d08d9430SMartin Schwidefsky struct sclp_core_entry *cpue; 26217a4406SHeiko Carstens u16 boot_cpu_address, cpu; 27217a4406SHeiko Carstens 2817aacfbfSVasily Gorbik if (sclp_early_get_info(sccb)) 29acf6a004SMichael Holzheu return; 30acf6a004SMichael Holzheu 3178335a30SDavid Hildenbrand sclp.facilities = sccb->facilities; 3237c5f6c8SDavid Hildenbrand sclp.has_sprp = !!(sccb->fac84 & 0x02); 33d08d9430SMartin Schwidefsky sclp.has_core_type = !!(sccb->fac84 & 0x01); 345236c751SDavid Hildenbrand sclp.has_gsls = !!(sccb->fac85 & 0x80); 354013ade3SDavid Hildenbrand sclp.has_64bscao = !!(sccb->fac116 & 0x80); 3609be9cb9SDavid Hildenbrand sclp.has_cmma = !!(sccb->fac116 & 0x40); 37f7ba1d34SEugene (jno) Dvurechenski sclp.has_esca = !!(sccb->fac116 & 0x08); 38a0eb55e6SDavid Hildenbrand sclp.has_pfmfi = !!(sccb->fac117 & 0x40); 399c375490SDavid Hildenbrand sclp.has_ibs = !!(sccb->fac117 & 0x20); 409e73ea70SMichael Mueller sclp.has_gisaf = !!(sccb->fac118 & 0x08); 41f7ba1d34SEugene (jno) Dvurechenski sclp.has_hvs = !!(sccb->fac119 & 0x80); 4271cb1bf6SFarhan Ali sclp.has_kss = !!(sccb->fac98 & 0x01); 43*4df9a825SPhilipp Rudo sclp.has_sipl = !!(sccb->cbl & 0x4000); 44acf6a004SMichael Holzheu if (sccb->fac85 & 0x02) 45acf6a004SMichael Holzheu S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; 46118bd31bSMartin Schwidefsky if (sccb->fac91 & 0x40) 47118bd31bSMartin Schwidefsky S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; 484ad78b86SCollin Walling if (sccb->cpuoff > 134) 494ad78b86SCollin Walling sclp.has_diag318 = !!(sccb->byte_134 & 0x80); 5037c5f6c8SDavid Hildenbrand sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; 5137c5f6c8SDavid Hildenbrand sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 5237c5f6c8SDavid Hildenbrand sclp.rzm <<= 20; 5337c5f6c8SDavid Hildenbrand sclp.ibc = sccb->ibc; 54333cce91SHendrik Brueckner 5532e6b236SGuenther Hutzl if (sccb->hamaxpow && sccb->hamaxpow < 64) 5632e6b236SGuenther Hutzl sclp.hamax = (1UL << sccb->hamaxpow) - 1; 5732e6b236SGuenther Hutzl else 5832e6b236SGuenther Hutzl sclp.hamax = U64_MAX; 5932e6b236SGuenther Hutzl 60cf813db0SHeiko Carstens if (!sccb->hcpua) { 61cf813db0SHeiko Carstens if (MACHINE_IS_VM) 62d08d9430SMartin Schwidefsky sclp.max_cores = 64; 63cf813db0SHeiko Carstens else 64d08d9430SMartin Schwidefsky sclp.max_cores = sccb->ncpurl; 65cf813db0SHeiko Carstens } else { 66d08d9430SMartin Schwidefsky sclp.max_cores = sccb->hcpua + 1; 67cf813db0SHeiko Carstens } 68cf813db0SHeiko Carstens 69217a4406SHeiko Carstens boot_cpu_address = stap(); 70217a4406SHeiko Carstens cpue = (void *)sccb + sccb->cpuoff; 71217a4406SHeiko Carstens for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { 7210ad34bcSMartin Schwidefsky if (boot_cpu_address != cpue->core_id) 73217a4406SHeiko Carstens continue; 7437c5f6c8SDavid Hildenbrand sclp.has_siif = cpue->siif; 7537c5f6c8SDavid Hildenbrand sclp.has_sigpif = cpue->sigpif; 768dfd523fSDavid Hildenbrand sclp.has_sief2 = cpue->sief2; 77b9e28897SDavid Hildenbrand sclp.has_gpere = cpue->gpere; 7872cd82b9SDavid Hildenbrand sclp.has_ib = cpue->ib; 794a5c3e08SDavid Hildenbrand sclp.has_cei = cpue->cei; 8023861451SDavid Hildenbrand sclp.has_skey = cpue->skey; 81217a4406SHeiko Carstens break; 82217a4406SHeiko Carstens } 83217a4406SHeiko Carstens 84333cce91SHendrik Brueckner /* Save IPL information */ 85333cce91SHendrik Brueckner sclp_ipl_info.is_valid = 1; 86118bd31bSMartin Schwidefsky if (sccb->fac91 & 0x2) 87333cce91SHendrik Brueckner sclp_ipl_info.has_dump = 1; 88333cce91SHendrik Brueckner memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); 8910ad34bcSMartin Schwidefsky 903b076dcaSVasily Gorbik if (sccb->hsa_size) 913b076dcaSVasily Gorbik sclp.hsa_size = (sccb->hsa_size - 1) * PAGE_SIZE; 9237c5f6c8SDavid Hildenbrand sclp.mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; 9337c5f6c8SDavid Hildenbrand sclp.mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; 9437c5f6c8SDavid Hildenbrand sclp.mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; 95154fa27eSAlexander Yarygin 96154fa27eSAlexander Yarygin sclp.hmfai = sccb->hmfai; 970a9fddfaSSebastian Ott sclp.has_dirq = !!(sccb->cpudirq & 0x80); 98acf6a004SMichael Holzheu } 99acf6a004SMichael Holzheu 100acf6a004SMichael Holzheu /* 101d5ab7a34SHeiko Carstens * This function will be called after sclp_early_facilities_detect(), which gets 102d5ab7a34SHeiko Carstens * called from early.c code. The sclp_early_facilities_detect() function retrieves 103333cce91SHendrik Brueckner * and saves the IPL information. 104acf6a004SMichael Holzheu */ 105d5ab7a34SHeiko Carstens void __init sclp_early_get_ipl_info(struct sclp_ipl_info *info) 106acf6a004SMichael Holzheu { 107333cce91SHendrik Brueckner *info = sclp_ipl_info; 108acf6a004SMichael Holzheu } 109acf6a004SMichael Holzheu 110d5ab7a34SHeiko Carstens static struct sclp_core_info sclp_early_core_info __initdata; 111d5ab7a34SHeiko Carstens static int sclp_early_core_info_valid __initdata; 112e657d8feSMichael Holzheu 113d5ab7a34SHeiko Carstens static void __init sclp_early_init_core_info(struct read_cpu_info_sccb *sccb) 114af51160eSHeiko Carstens { 115af51160eSHeiko Carstens if (!SCLP_HAS_CPU_INFO) 116af51160eSHeiko Carstens return; 117af51160eSHeiko Carstens memset(sccb, 0, sizeof(*sccb)); 118af51160eSHeiko Carstens sccb->header.length = sizeof(*sccb); 119f694bb3aSHeiko Carstens if (sclp_early_cmd(SCLP_CMDW_READ_CPU_INFO, sccb)) 120af51160eSHeiko Carstens return; 121af51160eSHeiko Carstens if (sccb->header.response_code != 0x0010) 122af51160eSHeiko Carstens return; 123d5ab7a34SHeiko Carstens sclp_fill_core_info(&sclp_early_core_info, sccb); 124d5ab7a34SHeiko Carstens sclp_early_core_info_valid = 1; 125af51160eSHeiko Carstens } 126af51160eSHeiko Carstens 127d5ab7a34SHeiko Carstens int __init sclp_early_get_core_info(struct sclp_core_info *info) 128af51160eSHeiko Carstens { 129d5ab7a34SHeiko Carstens if (!sclp_early_core_info_valid) 130af51160eSHeiko Carstens return -EIO; 131d5ab7a34SHeiko Carstens *info = sclp_early_core_info; 132af51160eSHeiko Carstens return 0; 133af51160eSHeiko Carstens } 134af51160eSHeiko Carstens 135d5ab7a34SHeiko Carstens static void __init sclp_early_console_detect(struct init_sccb *sccb) 13652733e01SHendrik Brueckner { 13752733e01SHendrik Brueckner if (sccb->header.response_code != 0x20) 13852733e01SHendrik Brueckner return; 13952733e01SHendrik Brueckner 140b8435635SClaudio Imbrenda if (sclp_early_con_check_vt220(sccb)) 14137c5f6c8SDavid Hildenbrand sclp.has_vt220 = 1; 14252733e01SHendrik Brueckner 143d5ab7a34SHeiko Carstens if (sclp_early_con_check_linemode(sccb)) 14437c5f6c8SDavid Hildenbrand sclp.has_linemode = 1; 14552733e01SHendrik Brueckner } 14652733e01SHendrik Brueckner 1477b50da53SMichael Holzheu void __init sclp_early_detect(void) 1487b50da53SMichael Holzheu { 149087c4d74SGerald Schaefer void *sccb = sclp_early_sccb; 1505d5de1a0SHendrik Brueckner 151d5ab7a34SHeiko Carstens sclp_early_facilities_detect(sccb); 152d5ab7a34SHeiko Carstens sclp_early_init_core_info(sccb); 15352733e01SHendrik Brueckner 154d5ab7a34SHeiko Carstens /* 155d5ab7a34SHeiko Carstens * Turn off SCLP event notifications. Also save remote masks in the 15652733e01SHendrik Brueckner * sccb. These are sufficient to detect sclp console capabilities. 15752733e01SHendrik Brueckner */ 158d5ab7a34SHeiko Carstens sclp_early_set_event_mask(sccb, 0, 0); 159d5ab7a34SHeiko Carstens sclp_early_console_detect(sccb); 1607b50da53SMichael Holzheu } 161