Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * drmem.h: Power specific logical memory block representation
0004  *
0005  * Copyright 2017 IBM Corporation
0006  */
0007 
0008 #ifndef _ASM_POWERPC_LMB_H
0009 #define _ASM_POWERPC_LMB_H
0010 
0011 #include <linux/sched.h>
0012 
0013 struct drmem_lmb {
0014     u64     base_addr;
0015     u32     drc_index;
0016     u32     aa_index;
0017     u32     flags;
0018 };
0019 
0020 struct drmem_lmb_info {
0021     struct drmem_lmb        *lmbs;
0022     int                     n_lmbs;
0023     u64                     lmb_size;
0024 };
0025 
0026 struct device_node;
0027 struct property;
0028 
0029 extern struct drmem_lmb_info *drmem_info;
0030 
0031 static inline struct drmem_lmb *drmem_lmb_next(struct drmem_lmb *lmb,
0032                            const struct drmem_lmb *start)
0033 {
0034     /*
0035      * DLPAR code paths can take several milliseconds per element
0036      * when interacting with firmware. Ensure that we don't
0037      * unfairly monopolize the CPU.
0038      */
0039     if (((++lmb - start) % 16) == 0)
0040         cond_resched();
0041 
0042     return lmb;
0043 }
0044 
0045 #define for_each_drmem_lmb_in_range(lmb, start, end)        \
0046     for ((lmb) = (start); (lmb) < (end); lmb = drmem_lmb_next(lmb, start))
0047 
0048 #define for_each_drmem_lmb(lmb)                 \
0049     for_each_drmem_lmb_in_range((lmb),          \
0050         &drmem_info->lmbs[0],               \
0051         &drmem_info->lmbs[drmem_info->n_lmbs])
0052 
0053 /*
0054  * The of_drconf_cell_v1 struct defines the layout of the LMB data
0055  * specified in the ibm,dynamic-memory device tree property.
0056  * The property itself is a 32-bit value specifying the number of
0057  * LMBs followed by an array of of_drconf_cell_v1 entries, one
0058  * per LMB.
0059  */
0060 struct of_drconf_cell_v1 {
0061     __be64  base_addr;
0062     __be32  drc_index;
0063     __be32  reserved;
0064     __be32  aa_index;
0065     __be32  flags;
0066 };
0067 
0068 /*
0069  * Version 2 of the ibm,dynamic-memory property is defined as a
0070  * 32-bit value specifying the number of LMB sets followed by an
0071  * array of of_drconf_cell_v2 entries, one per LMB set.
0072  */
0073 struct of_drconf_cell_v2 {
0074     u32 seq_lmbs;
0075     u64 base_addr;
0076     u32 drc_index;
0077     u32 aa_index;
0078     u32 flags;
0079 } __packed;
0080 
0081 #define DRCONF_MEM_ASSIGNED 0x00000008
0082 #define DRCONF_MEM_AI_INVALID   0x00000040
0083 #define DRCONF_MEM_RESERVED 0x00000080
0084 #define DRCONF_MEM_HOTREMOVABLE 0x00000100
0085 
0086 static inline u64 drmem_lmb_size(void)
0087 {
0088     return drmem_info->lmb_size;
0089 }
0090 
0091 #define DRMEM_LMB_RESERVED  0x80000000
0092 
0093 static inline void drmem_mark_lmb_reserved(struct drmem_lmb *lmb)
0094 {
0095     lmb->flags |= DRMEM_LMB_RESERVED;
0096 }
0097 
0098 static inline void drmem_remove_lmb_reservation(struct drmem_lmb *lmb)
0099 {
0100     lmb->flags &= ~DRMEM_LMB_RESERVED;
0101 }
0102 
0103 static inline bool drmem_lmb_reserved(struct drmem_lmb *lmb)
0104 {
0105     return lmb->flags & DRMEM_LMB_RESERVED;
0106 }
0107 
0108 u64 drmem_lmb_memory_max(void);
0109 int walk_drmem_lmbs(struct device_node *dn, void *data,
0110             int (*func)(struct drmem_lmb *, const __be32 **, void *));
0111 int drmem_update_dt(void);
0112 
0113 #ifdef CONFIG_PPC_PSERIES
0114 int __init
0115 walk_drmem_lmbs_early(unsigned long node, void *data,
0116               int (*func)(struct drmem_lmb *, const __be32 **, void *));
0117 void drmem_update_lmbs(struct property *prop);
0118 #endif
0119 
0120 static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb)
0121 {
0122     lmb->aa_index = 0xffffffff;
0123 }
0124 
0125 #endif /* _ASM_POWERPC_LMB_H */