blob: 9e8c70457aeea833e0378bd3bd3f3edd23ccbb99 [file] [log] [blame]
Aaron Durbina05a8522013-03-22 20:44:46 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Aaron Durbina05a8522013-03-22 20:44:46 -050014 */
15#ifndef MEMRANGE_H_
16#define MEMRANGE_H_
17
18#include <device/resource.h>
19
20/* A memranges structure consists of a list of range_entry(s). The structure
21 * is exposed so that a memranges can be used on the stack if needed. */
22struct memranges {
23 struct range_entry *entries;
24};
25
26/* Each region within a memranges structure is represented by a
27 * range_entry structure. Use the associated range_entry_(base|end|size|tag)
28 * functions to interrogate its properties. i.e. don't rely on one's own
29 * interpretation of the fields. */
30struct range_entry {
31 resource_t begin;
32 resource_t end;
33 unsigned long tag;
34 struct range_entry *next;
35};
36
37/* Return inclusive base address of memory range. */
38static inline resource_t range_entry_base(const struct range_entry *r)
39{
40 return r->begin;
41}
42
43/* Return exclusive end address of memory range. */
44static inline resource_t range_entry_end(const struct range_entry *r)
45{
46 return r->end + 1;
47}
48
49/* Return size of of memory range. */
50static inline resource_t range_entry_size(const struct range_entry *r)
51{
52 return r->end - r->begin + 1;
53}
54
55static inline unsigned long range_entry_tag(const struct range_entry *r)
56{
57 return r->tag;
58}
59
Aaron Durbinf6f6e132013-03-26 21:22:42 -050060static inline void range_entry_update_tag(struct range_entry *r,
61 unsigned long new_tag)
62{
63 r->tag = new_tag;
64}
65
Aaron Durbina05a8522013-03-22 20:44:46 -050066/* Iterate over each entry in a memranges structure. Ranges cannot
67 * be deleted while processing each entry as the list cannot be safely
68 * traversed after such an operation.
69 * r - range_entry pointer.
70 * ranges - memranges pointer */
71#define memranges_each_entry(r, ranges) \
72 for (r = (ranges)->entries; r != NULL; r = r->next)
73
Furquan Shaikh196ee2b2014-07-18 10:25:54 -070074/* Initialize memranges structure */
75void memranges_init_empty(struct memranges *ranges);
76
Aaron Durbina05a8522013-03-22 20:44:46 -050077/* Initialize and fill a memranges structure according to the
78 * mask and match type for all memory resources. Tag each entry with the
79 * specified type. */
80void memranges_init(struct memranges *ranges,
81 unsigned long mask, unsigned long match,
82 unsigned long tag);
83
84/* Remove and free all entries within the memranges structure. */
85void memranges_teardown(struct memranges *ranges);
86
87/* Add memory resources that match with the corresponding mask and match.
88 * Each entry will be tagged with the provided tag. e.g. To populate
89 * all cacheable memory resources in the range:
90 * memranges_add_resources(range, IORESOURCE_CACHEABLE,
91 * IORESROUCE_CACHEABLE, my_cacheable_tag); */
92void memranges_add_resources(struct memranges *ranges,
93 unsigned long mask, unsigned long match,
94 unsigned long tag);
95
Aaron Durbinca4f4b82014-02-08 15:41:52 -060096/* Add memory resources that match with the corresponding mask and match but
97 * also provide filter as additional check. The filter will return non-zero
98 * to add the resource or zero to not add the resource. Each entry will be
99 * tagged with the provided tag. e.g. To populate all cacheable memory
100 * resources in the range with a filter:
101 * memranges_add_resources_filter(range, IORESOURCE_CACHEABLE,
102 * IORESROUCE_CACHEABLE, my_cacheable_tag, filter); */
103typedef int (*memrange_filter_t)(struct device *dev, struct resource *res);
104void memranges_add_resources_filter(struct memranges *ranges,
105 unsigned long mask, unsigned long match,
106 unsigned long tag,
107 memrange_filter_t filter);
108
Aaron Durbina05a8522013-03-22 20:44:46 -0500109/* Fill all address ranges up to limit (exclusive) not covered by an entry by
110 * inserting new entries with the provided tag. */
111void memranges_fill_holes_up_to(struct memranges *ranges,
112 resource_t limit, unsigned long tag);
113
114/* Create a hole in the range by deleting/modifying entries that overlap with
115 * the region specified by base and size. */
116void memranges_create_hole(struct memranges *ranges,
117 resource_t base, resource_t size);
118
119/* Insert a resource to the given memranges. All existing ranges
120 * covered by range specified by base and size will be removed before a
121 * new one is added. */
122void memranges_insert(struct memranges *ranges,
123 resource_t base, resource_t size, unsigned long tag);
124
Aaron Durbined9307d2014-02-05 15:44:30 -0600125/* Update all entries with old_tag to new_tag. */
126void memranges_update_tag(struct memranges *ranges, unsigned long old_tag,
127 unsigned long new_tag);
128
Aaron Durbinf6f6e132013-03-26 21:22:42 -0500129/* Returns next entry after the provided entry. NULL if r is last. */
130struct range_entry *memranges_next_entry(struct memranges *ranges,
131 const struct range_entry *r);
Aaron Durbina05a8522013-03-22 20:44:46 -0500132#endif /* MEMRANGE_H_ */