drivers/s390/char/sclp_early.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/sclp_early.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/sclp_early.c
Extension
.c
Size
4876 bytes
Lines
188
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * SCLP early driver
 *
 * Copyright IBM Corp. 2013
 */

#define pr_fmt(fmt) "sclp_early: " fmt

#include <linux/export.h>
#include <linux/errno.h>
#include <linux/memblock.h>
#include <asm/ctlreg.h>
#include <asm/sclp.h>
#include <asm/ipl.h>
#include <asm/setup.h>
#include <asm/facility.h>
#include "sclp_sdias.h"
#include "sclp.h"

static struct sclp_ipl_info sclp_ipl_info;

struct sclp_info sclp;
EXPORT_SYMBOL(sclp);

static void __init sclp_early_facilities_detect(void)
{
	struct sclp_core_entry *cpue;
	struct read_info_sccb *sccb;
	u16 boot_cpu_address, cpu;

	sccb = sclp_early_get_info();
	if (!sccb)
		return;

	sclp.facilities = sccb->facilities;
	sclp.has_sprp = !!(sccb->fac84 & 0x02);
	sclp.has_core_type = !!(sccb->fac84 & 0x01);
	sclp.has_gsls = !!(sccb->fac85 & 0x80);
	sclp.has_64bscao = !!(sccb->fac116 & 0x80);
	sclp.has_cmma = !!(sccb->fac116 & 0x40);
	sclp.has_esca = !!(sccb->fac116 & 0x08);
	sclp.has_pfmfi = !!(sccb->fac117 & 0x40);
	sclp.has_ibs = !!(sccb->fac117 & 0x20);
	sclp.has_gisaf = !!(sccb->fac118 & 0x08);
	sclp.has_hvs = !!(sccb->fac119 & 0x80);
	sclp.has_wti = !!(sccb->fac119 & 0x40);
	sclp.has_kss = !!(sccb->fac98 & 0x01);
	sclp.has_aisii = !!(sccb->fac118 & 0x40);
	sclp.has_aeni = !!(sccb->fac118 & 0x20);
	sclp.has_aisi = !!(sccb->fac118 & 0x10);
	sclp.has_zpci_lsi = !!(sccb->fac118 & 0x01);
	sclp.has_diag204_bif = !!(sccb->fac98 & 0x80);
	sclp.has_diag310 = !!(sccb->fac91 & 0x80);
	if (sccb->cpuoff > 134) {
		sclp.has_diag318 = !!(sccb->byte_134 & 0x80);
		sclp.has_diag320 = !!(sccb->byte_134 & 0x04);
		sclp.has_iplcc = !!(sccb->byte_134 & 0x02);
	}
	if (sccb->cpuoff > 137) {
		sclp.has_sipl = !!(sccb->cbl & 0x4000);
		sclp.has_sipl_eckd = !!(sccb->cbl & 0x2000);
	}
	if (sccb->cpuoff > 139) {
		sclp.has_diag324 = !!(sccb->byte_139 & 0x80);
		sclp.has_astfleie2 = !!(sccb->byte_139 & 0x40);
	}
	sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
	sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
	sclp.rzm <<= 20;
	sclp.ibc = sccb->ibc;

	if (sccb->hamaxpow && sccb->hamaxpow < 64)
		sclp.hamax = (1UL << sccb->hamaxpow) - 1;
	else
		sclp.hamax = U64_MAX;

	if (!sccb->hcpua) {
		if (machine_is_vm())
			sclp.max_cores = 64;
		else
			sclp.max_cores = sccb->ncpurl;
	} else {
		sclp.max_cores = sccb->hcpua + 1;
	}

	boot_cpu_address = stap();
	cpue = (void *)sccb + sccb->cpuoff;
	for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) {
		if (boot_cpu_address != cpue->core_id)

Annotation

Implementation Notes