diff options
Diffstat (limited to 'arch/s390/include/asm/physmem_info.h')
| -rw-r--r-- | arch/s390/include/asm/physmem_info.h | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/arch/s390/include/asm/physmem_info.h b/arch/s390/include/asm/physmem_info.h index d5e65a5d06e7..27234fa1da8e 100644 --- a/arch/s390/include/asm/physmem_info.h +++ b/arch/s390/include/asm/physmem_info.h @@ -17,6 +17,27 @@ struct physmem_range { u64 end; }; +enum reserved_range_type { + RR_DECOMPRESSOR, + RR_INITRD, + RR_VMLINUX, + RR_AMODE31, + RR_IPLREPORT, + RR_CERT_COMP_LIST, + RR_MEM_DETECT_EXTENDED, + RR_VMEM, +#ifdef CONFIG_KASAN + RR_KASAN, +#endif + RR_MAX +}; + +struct reserved_range { + unsigned long start; + unsigned long end; + struct reserved_range *chain; +}; + /* * Storage element id is defined as 1 byte (up to 256 storage elements). * In practise only storage element id 0 and 1 are used). @@ -31,6 +52,7 @@ struct physmem_info { u32 range_count; u8 info_source; unsigned long usable; + struct reserved_range reserved[RR_MAX]; struct physmem_range online[MEM_INLINED_ENTRIES]; struct physmem_range *online_extended; }; @@ -80,6 +102,70 @@ static inline int __get_physmem_range(u32 n, unsigned long *start, #define for_each_physmem_online_range(i, p_start, p_end) \ for (i = 0; !__get_physmem_range(i, p_start, p_end, false); i++) +static inline const char *get_physmem_info_source(void) +{ + switch (physmem_info.info_source) { + case MEM_DETECT_SCLP_STOR_INFO: + return "sclp storage info"; + case MEM_DETECT_DIAG260: + return "diag260"; + case MEM_DETECT_SCLP_READ_INFO: + return "sclp read info"; + case MEM_DETECT_BIN_SEARCH: + return "binary search"; + } + return "none"; +} + +#define RR_TYPE_NAME(t) case RR_ ## t: return #t +static inline const char *get_rr_type_name(enum reserved_range_type t) +{ + switch (t) { + RR_TYPE_NAME(DECOMPRESSOR); + RR_TYPE_NAME(INITRD); + RR_TYPE_NAME(VMLINUX); + RR_TYPE_NAME(AMODE31); + RR_TYPE_NAME(IPLREPORT); + RR_TYPE_NAME(CERT_COMP_LIST); + RR_TYPE_NAME(MEM_DETECT_EXTENDED); + RR_TYPE_NAME(VMEM); +#ifdef CONFIG_KASAN + RR_TYPE_NAME(KASAN); +#endif + default: + return "UNKNOWN"; + } +} + +#define for_each_physmem_reserved_type_range(t, range, p_start, p_end) \ + for (range = &physmem_info.reserved[t], *p_start = range->start, *p_end = range->end; \ + range && range->end; range = range->chain, \ + *p_start = range ? range->start : 0, *p_end = range ? range->end : 0) + +static inline struct reserved_range *__physmem_reserved_next(enum reserved_range_type *t, + struct reserved_range *range) +{ + if (!range) { + range = &physmem_info.reserved[*t]; + if (range->end) + return range; + } + if (range->chain) + return range->chain; + while (++*t < RR_MAX) { + range = &physmem_info.reserved[*t]; + if (range->end) + return range; + } + return NULL; +} + +#define for_each_physmem_reserved_range(t, range, p_start, p_end) \ + for (t = 0, range = __physmem_reserved_next(&t, NULL), \ + *p_start = range ? range->start : 0, *p_end = range ? range->end : 0; \ + range; range = __physmem_reserved_next(&t, range), \ + *p_start = range ? range->start : 0, *p_end = range ? range->end : 0) + static inline unsigned long get_physmem_usable_total(void) { unsigned long start, end, total = 0; @@ -91,28 +177,12 @@ static inline unsigned long get_physmem_usable_total(void) return total; } -static inline void get_physmem_reserved(unsigned long *start, unsigned long *size) +static inline unsigned long get_physmem_reserved(enum reserved_range_type type, + unsigned long *addr, unsigned long *size) { - *start = (unsigned long)physmem_info.online_extended; - if (physmem_info.range_count > MEM_INLINED_ENTRIES) - *size = (physmem_info.range_count - MEM_INLINED_ENTRIES) * - sizeof(struct physmem_range); - else - *size = 0; -} - -static inline unsigned long get_physmem_usable_end(void) -{ - unsigned long start; - unsigned long end; - - if (physmem_info.usable) - return physmem_info.usable; - if (physmem_info.range_count) { - __get_physmem_range(physmem_info.range_count - 1, &start, &end, false); - return end; - } - return 0; + *addr = physmem_info.reserved[type].start; + *size = physmem_info.reserved[type].end - physmem_info.reserved[type].start; + return *size; } #endif |
