Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/s390/kernel/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 2 kB image not shown  

Quelle  ctlreg.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corp. 1999, 2023
 */


#include <linux/irqflags.h>
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/cache.h>
#include <asm/abs_lowcore.h>
#include <asm/ctlreg.h>

/*
 * ctl_lock guards access to global control register contents which
 * are kept in the control register save area within absolute lowcore
 * at physical address zero.
 */

static DEFINE_SPINLOCK(system_ctl_lock);

void system_ctlreg_lock(void)
 __acquires(&system_ctl_lock)
{
 spin_lock(&system_ctl_lock);
}

void system_ctlreg_unlock(void)
 __releases(&system_ctl_lock)
{
 spin_unlock(&system_ctl_lock);
}

static bool system_ctlreg_area_init __ro_after_init;

void __init system_ctlreg_init_save_area(struct lowcore *lc)
{
 struct lowcore *abs_lc;

 abs_lc = get_abs_lowcore();
 __local_ctl_store(0, 15, lc->cregs_save_area);
 __local_ctl_store(0, 15, abs_lc->cregs_save_area);
 put_abs_lowcore(abs_lc);
 system_ctlreg_area_init = true;
}

struct ctlreg_parms {
 unsigned long andval;
 unsigned long orval;
 unsigned long val;
 int request;
 int cr;
};

static void ctlreg_callback(void *info)
{
 struct ctlreg_parms *pp = info;
 struct ctlreg regs[16];

 __local_ctl_store(0, 15, regs);
 if (pp->request == CTLREG_LOAD) {
  regs[pp->cr].val = pp->val;
 } else {
  regs[pp->cr].val &= pp->andval;
  regs[pp->cr].val |= pp->orval;
 }
 __local_ctl_load(0, 15, regs);
}

static void system_ctlreg_update(void *info)
{
 unsigned long flags;

 if (system_state == SYSTEM_BOOTING) {
  /*
 * For very early calls do not call on_each_cpu()
 * since not everything might be setup.
 */

  local_irq_save(flags);
  ctlreg_callback(info);
  local_irq_restore(flags);
 } else {
  on_each_cpu(ctlreg_callback, info, 1);
 }
}

void system_ctlreg_modify(unsigned int cr, unsigned long data, int request)
{
 struct ctlreg_parms pp = { .cr = cr, .request = request, };
 struct lowcore *abs_lc;

 switch (request) {
 case CTLREG_SET_BIT:
  pp.orval  = 1UL << data;
  pp.andval = -1UL;
  break;
 case CTLREG_CLEAR_BIT:
  pp.orval  = 0;
  pp.andval = ~(1UL << data);
  break;
 case CTLREG_LOAD:
  pp.val = data;
  break;
 }
 if (system_ctlreg_area_init) {
  system_ctlreg_lock();
  abs_lc = get_abs_lowcore();
  if (request == CTLREG_LOAD) {
   abs_lc->cregs_save_area[cr].val = pp.val;
  } else {
   abs_lc->cregs_save_area[cr].val &= pp.andval;
   abs_lc->cregs_save_area[cr].val |= pp.orval;
  }
  put_abs_lowcore(abs_lc);
  system_ctlreg_update(&pp);
  system_ctlreg_unlock();
 } else {
  system_ctlreg_update(&pp);
 }
}
EXPORT_SYMBOL(system_ctlreg_modify);

Messung V0.5
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.