drmem.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * drmem.h: Power specific logical memory block representation
  4. *
  5. * Copyright 2017 IBM Corporation
  6. */
  7. #ifndef _ASM_POWERPC_LMB_H
  8. #define _ASM_POWERPC_LMB_H
  9. #include <linux/sched.h>
  10. struct drmem_lmb {
  11. u64 base_addr;
  12. u32 drc_index;
  13. u32 aa_index;
  14. u32 flags;
  15. };
  16. struct drmem_lmb_info {
  17. struct drmem_lmb *lmbs;
  18. int n_lmbs;
  19. u64 lmb_size;
  20. };
  21. struct device_node;
  22. struct property;
  23. extern struct drmem_lmb_info *drmem_info;
  24. static inline struct drmem_lmb *drmem_lmb_next(struct drmem_lmb *lmb,
  25. const struct drmem_lmb *start)
  26. {
  27. /*
  28. * DLPAR code paths can take several milliseconds per element
  29. * when interacting with firmware. Ensure that we don't
  30. * unfairly monopolize the CPU.
  31. */
  32. if (((++lmb - start) % 16) == 0)
  33. cond_resched();
  34. return lmb;
  35. }
  36. #define for_each_drmem_lmb_in_range(lmb, start, end) \
  37. for ((lmb) = (start); (lmb) < (end); lmb = drmem_lmb_next(lmb, start))
  38. #define for_each_drmem_lmb(lmb) \
  39. for_each_drmem_lmb_in_range((lmb), \
  40. &drmem_info->lmbs[0], \
  41. &drmem_info->lmbs[drmem_info->n_lmbs])
  42. /*
  43. * The of_drconf_cell_v1 struct defines the layout of the LMB data
  44. * specified in the ibm,dynamic-memory device tree property.
  45. * The property itself is a 32-bit value specifying the number of
  46. * LMBs followed by an array of of_drconf_cell_v1 entries, one
  47. * per LMB.
  48. */
  49. struct of_drconf_cell_v1 {
  50. __be64 base_addr;
  51. __be32 drc_index;
  52. __be32 reserved;
  53. __be32 aa_index;
  54. __be32 flags;
  55. };
  56. /*
  57. * Version 2 of the ibm,dynamic-memory property is defined as a
  58. * 32-bit value specifying the number of LMB sets followed by an
  59. * array of of_drconf_cell_v2 entries, one per LMB set.
  60. */
  61. struct of_drconf_cell_v2 {
  62. u32 seq_lmbs;
  63. u64 base_addr;
  64. u32 drc_index;
  65. u32 aa_index;
  66. u32 flags;
  67. } __packed;
  68. #define DRCONF_MEM_ASSIGNED 0x00000008
  69. #define DRCONF_MEM_AI_INVALID 0x00000040
  70. #define DRCONF_MEM_RESERVED 0x00000080
  71. #define DRCONF_MEM_HOTREMOVABLE 0x00000100
  72. static inline u64 drmem_lmb_size(void)
  73. {
  74. return drmem_info->lmb_size;
  75. }
  76. #define DRMEM_LMB_RESERVED 0x80000000
  77. static inline void drmem_mark_lmb_reserved(struct drmem_lmb *lmb)
  78. {
  79. lmb->flags |= DRMEM_LMB_RESERVED;
  80. }
  81. static inline void drmem_remove_lmb_reservation(struct drmem_lmb *lmb)
  82. {
  83. lmb->flags &= ~DRMEM_LMB_RESERVED;
  84. }
  85. static inline bool drmem_lmb_reserved(struct drmem_lmb *lmb)
  86. {
  87. return lmb->flags & DRMEM_LMB_RESERVED;
  88. }
  89. u64 drmem_lmb_memory_max(void);
  90. int walk_drmem_lmbs(struct device_node *dn, void *data,
  91. int (*func)(struct drmem_lmb *, const __be32 **, void *));
  92. int drmem_update_dt(void);
  93. #ifdef CONFIG_PPC_PSERIES
  94. int __init
  95. walk_drmem_lmbs_early(unsigned long node, void *data,
  96. int (*func)(struct drmem_lmb *, const __be32 **, void *));
  97. void drmem_update_lmbs(struct property *prop);
  98. #endif
  99. static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb)
  100. {
  101. lmb->aa_index = 0xffffffff;
  102. }
  103. #endif /* _ASM_POWERPC_LMB_H */