memblock.h 4.4 KB
Newer Older
Y
Yinghai Lu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#ifndef _LINUX_MEMBLOCK_H
#define _LINUX_MEMBLOCK_H
#ifdef __KERNEL__

/*
 * Logical memory blocks.
 *
 * Copyright (C) 2001 Peter Bergner, IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/init.h>
#include <linux/mm.h>

19 20
#include <asm/memblock.h>

21
#define INIT_MEMBLOCK_REGIONS 128
Y
Yinghai Lu 已提交
22

23
struct memblock_region {
24 25
	phys_addr_t base;
	phys_addr_t size;
Y
Yinghai Lu 已提交
26 27
};

28
struct memblock_type {
29 30 31
	unsigned long cnt;	/* number of regions */
	unsigned long max;	/* size of the allocated array */
	struct memblock_region *regions;
Y
Yinghai Lu 已提交
32 33 34
};

struct memblock {
35
	phys_addr_t current_limit;
36
	phys_addr_t memory_size;	/* Updated by memblock_analyze() */
37 38
	struct memblock_type memory;
	struct memblock_type reserved;
Y
Yinghai Lu 已提交
39 40 41 42 43 44
};

extern struct memblock memblock;

extern void __init memblock_init(void);
extern void __init memblock_analyze(void);
45 46 47 48
extern long memblock_add(phys_addr_t base, phys_addr_t size);
extern long memblock_remove(phys_addr_t base, phys_addr_t size);
extern long __init memblock_free(phys_addr_t base, phys_addr_t size);
extern long __init memblock_reserve(phys_addr_t base, phys_addr_t size);
49

50 51
extern phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid);
extern phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align);
52 53

/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */
54
#define MEMBLOCK_ALLOC_ANYWHERE	(~(phys_addr_t)0)
55 56
#define MEMBLOCK_ALLOC_ACCESSIBLE	0

57
extern phys_addr_t __init memblock_alloc_base(phys_addr_t size,
58 59
					 phys_addr_t align,
					 phys_addr_t max_addr);
60
extern phys_addr_t __init __memblock_alloc_base(phys_addr_t size,
61 62
					   phys_addr_t align,
					   phys_addr_t max_addr);
63 64 65 66 67 68 69
extern phys_addr_t __init memblock_phys_mem_size(void);
extern phys_addr_t memblock_end_of_DRAM(void);
extern void __init memblock_enforce_memory_limit(phys_addr_t memory_limit);
extern int memblock_is_memory(phys_addr_t addr);
extern int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
extern int __init memblock_is_reserved(phys_addr_t addr);
extern int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
Y
Yinghai Lu 已提交
70 71 72

extern void memblock_dump_all(void);

73
/* Provided by the architecture */
74
extern phys_addr_t memblock_nid_range(phys_addr_t start, phys_addr_t end, int *nid);
75 76
extern int memblock_memory_can_coalesce(phys_addr_t addr1, phys_addr_t size1,
				   phys_addr_t addr2, phys_addr_t size2);
77

78 79 80 81 82 83
/**
 * memblock_set_current_limit - Set the current allocation limit to allow
 *                         limiting allocations to what is currently
 *                         accessible during boot
 * @limit: New limit value (physical address)
 */
84
extern void memblock_set_current_limit(phys_addr_t limit);
85

86

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
/*
 * pfn conversion functions
 *
 * While the memory MEMBLOCKs should always be page aligned, the reserved
 * MEMBLOCKs may not be. This accessor attempt to provide a very clear
 * idea of what they return for such non aligned MEMBLOCKs.
 */

/**
 * memblock_region_base_pfn - Return the lowest pfn intersecting with the region
 * @reg: memblock_region structure
 */
static inline unsigned long memblock_region_base_pfn(const struct memblock_region *reg)
{
	return reg->base >> PAGE_SHIFT;
}

/**
 * memblock_region_last_pfn - Return the highest pfn intersecting with the region
 * @reg: memblock_region structure
 */
static inline unsigned long memblock_region_last_pfn(const struct memblock_region *reg)
{
	return (reg->base + reg->size - 1) >> PAGE_SHIFT;
}

/**
 * memblock_region_end_pfn - Return the pfn of the first page following the region
 *                      but not intersecting it
 * @reg: memblock_region structure
 */
static inline unsigned long memblock_region_end_pfn(const struct memblock_region *reg)
{
	return memblock_region_last_pfn(reg) + 1;
}

/**
 * memblock_region_pages - Return the number of pages covering a region
 * @reg: memblock_region structure
 */
static inline unsigned long memblock_region_pages(const struct memblock_region *reg)
{
	return memblock_region_end_pfn(reg) - memblock_region_end_pfn(reg);
}

#define for_each_memblock(memblock_type, region)					\
	for (region = memblock.memblock_type.regions;				\
	     region < (memblock.memblock_type.regions + memblock.memblock_type.cnt);	\
	     region++)


Y
Yinghai Lu 已提交
138 139 140
#endif /* __KERNEL__ */

#endif /* _LINUX_MEMBLOCK_H */