linux/arch/s390/include/asm/facility.h
<<
>>
Prefs
   1/*
   2 * Copyright IBM Corp. 1999, 2009
   3 *
   4 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
   5 */
   6
   7#ifndef __ASM_FACILITY_H
   8#define __ASM_FACILITY_H
   9
  10#include <linux/string.h>
  11#include <linux/preempt.h>
  12#include <asm/lowcore.h>
  13
  14#define MAX_FACILITY_BIT (256*8)        /* stfle_fac_list has 256 bytes */
  15
  16static inline int __test_facility(unsigned long nr, void *facilities)
  17{
  18        unsigned char *ptr;
  19
  20        if (nr >= MAX_FACILITY_BIT)
  21                return 0;
  22        ptr = (unsigned char *) facilities + (nr >> 3);
  23        return (*ptr & (0x80 >> (nr & 7))) != 0;
  24}
  25
  26/*
  27 * The test_facility function uses the bit odering where the MSB is bit 0.
  28 * That makes it easier to query facility bits with the bit number as
  29 * documented in the Principles of Operation.
  30 */
  31static inline int test_facility(unsigned long nr)
  32{
  33        return __test_facility(nr, &S390_lowcore.stfle_fac_list);
  34}
  35
  36/**
  37 * stfle - Store facility list extended
  38 * @stfle_fac_list: array where facility list can be stored
  39 * @size: size of passed in array in double words
  40 */
  41static inline void stfle(u64 *stfle_fac_list, int size)
  42{
  43        unsigned long nr;
  44
  45        preempt_disable();
  46        asm volatile(
  47                "       .insn s,0xb2b10000,0(0)\n" /* stfl */
  48                "0:\n"
  49                EX_TABLE(0b, 0b)
  50                : "+m" (S390_lowcore.stfl_fac_list));
  51        nr = 4; /* bytes stored by stfl */
  52        memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
  53        if (S390_lowcore.stfl_fac_list & 0x01000000) {
  54                /* More facility bits available with stfle */
  55                register unsigned long reg0 asm("0") = size - 1;
  56
  57                asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
  58                             : "+d" (reg0)
  59                             : "a" (stfle_fac_list)
  60                             : "memory", "cc");
  61                nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
  62        }
  63        memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
  64        preempt_enable();
  65}
  66
  67#endif /* __ASM_FACILITY_H */
  68