diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-10-25 10:10:51 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-25 10:10:21 -0400 |
commit | 14375bc4eb8dd0fb0e765390650564c35bb31068 (patch) | |
tree | 27200620658245c582ee9497fc969a082b304cab /arch/s390/include | |
parent | eca577ef5989d25dedc6b0fae3c4622ceaee8005 (diff) |
[S390] cleanup facility list handling
Store the facility list once at system startup with stfl/stfle and
reuse the result for all facility tests.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include')
-rw-r--r-- | arch/s390/include/asm/lowcore.h | 11 | ||||
-rw-r--r-- | arch/s390/include/asm/system.h | 33 |
2 files changed, 20 insertions, 24 deletions
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 0f97ef2d92ac..65e172f8209d 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
@@ -150,9 +150,10 @@ struct _lowcore { | |||
150 | */ | 150 | */ |
151 | __u32 ipib; /* 0x0e00 */ | 151 | __u32 ipib; /* 0x0e00 */ |
152 | __u32 ipib_checksum; /* 0x0e04 */ | 152 | __u32 ipib_checksum; /* 0x0e04 */ |
153 | __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */ | ||
153 | 154 | ||
154 | /* Align to the top 1k of prefix area */ | 155 | /* Extended facility list */ |
155 | __u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */ | 156 | __u64 stfle_fac_list[32]; /* 0x0f00 */ |
156 | } __packed; | 157 | } __packed; |
157 | 158 | ||
158 | #else /* CONFIG_32BIT */ | 159 | #else /* CONFIG_32BIT */ |
@@ -285,7 +286,11 @@ struct _lowcore { | |||
285 | */ | 286 | */ |
286 | __u64 ipib; /* 0x0e00 */ | 287 | __u64 ipib; /* 0x0e00 */ |
287 | __u32 ipib_checksum; /* 0x0e08 */ | 288 | __u32 ipib_checksum; /* 0x0e08 */ |
288 | __u8 pad_0x0e0c[0x11b8-0x0e0c]; /* 0x0e0c */ | 289 | __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */ |
290 | |||
291 | /* Extended facility list */ | ||
292 | __u64 stfle_fac_list[32]; /* 0x0f00 */ | ||
293 | __u8 pad_0x1000[0x11b8-0x1000]; /* 0x1000 */ | ||
289 | 294 | ||
290 | /* 64 bit extparam used for pfault/diag 250: defined by architecture */ | 295 | /* 64 bit extparam used for pfault/diag 250: defined by architecture */ |
291 | __u64 ext_params2; /* 0x11B8 */ | 296 | __u64 ext_params2; /* 0x11B8 */ |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 3c079dd5ee79..3ad16dbf622e 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
@@ -420,30 +420,21 @@ extern void smp_ctl_clear_bit(int cr, int bit); | |||
420 | 420 | ||
421 | #endif /* CONFIG_SMP */ | 421 | #endif /* CONFIG_SMP */ |
422 | 422 | ||
423 | static inline unsigned int stfl(void) | 423 | #define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ |
424 | { | ||
425 | asm volatile( | ||
426 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | ||
427 | "0:\n" | ||
428 | EX_TABLE(0b,0b)); | ||
429 | return S390_lowcore.stfl_fac_list; | ||
430 | } | ||
431 | 424 | ||
432 | static inline int __stfle(unsigned long long *list, int doublewords) | 425 | /* |
426 | * The test_facility function uses the bit odering where the MSB is bit 0. | ||
427 | * That makes it easier to query facility bits with the bit number as | ||
428 | * documented in the Principles of Operation. | ||
429 | */ | ||
430 | static inline int test_facility(unsigned long nr) | ||
433 | { | 431 | { |
434 | typedef struct { unsigned long long _[doublewords]; } addrtype; | 432 | unsigned char *ptr; |
435 | register unsigned long __nr asm("0") = doublewords - 1; | ||
436 | |||
437 | asm volatile(".insn s,0xb2b00000,%0" /* stfle */ | ||
438 | : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc"); | ||
439 | return __nr + 1; | ||
440 | } | ||
441 | 433 | ||
442 | static inline int stfle(unsigned long long *list, int doublewords) | 434 | if (nr >= MAX_FACILITY_BIT) |
443 | { | 435 | return 0; |
444 | if (!(stfl() & (1UL << 24))) | 436 | ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3); |
445 | return -EOPNOTSUPP; | 437 | return (*ptr & (0x80 >> (nr & 7))) != 0; |
446 | return __stfle(list, doublewords); | ||
447 | } | 438 | } |
448 | 439 | ||
449 | static inline unsigned short stap(void) | 440 | static inline unsigned short stap(void) |