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