1 /* Copyright (c) 2009 The Regents of the University of California.
2 * See the COPYRIGHT files at the top of this source tree for full
5 * Kevin Klues <klueska@cs.berkeley.edu>
13 #include <ros/common.h>
15 #include <arch/bitmask.h>
16 #include <colored_caches.h>
21 #define l1 (available_caches.l1)
22 #define l2 (available_caches.l2)
23 #define l3 (available_caches.l3)
25 spinlock_t cache_colors_lock;
27 /************** Cache Related Functions *****************/
28 inline void init_cache_properties(cache_t *c, size_t sz_k, size_t wa, size_t clsz) {
30 c->sz_k = SINIT(sz_k);
31 c->clsz = SINIT(clsz);
33 //Added as optimization (derived from above);
34 size_t nc = get_cache_num_page_colors(c);
35 c->num_colors = SINIT(nc);
38 inline void init_free_cache_colors_map(cache_t* c)
40 // Initialize the free colors map
41 c->free_colors_map = kmalloc(c->num_colors, 0);
42 FILL_BITMASK(c->free_colors_map, c->num_colors);
45 inline size_t get_page_color(uintptr_t page, cache_t *c) {
46 return (page % c->num_colors);
48 inline size_t get_offset_in_cache_line(uintptr_t addr, cache_t *c) {
49 return (addr % get_cache_bytes_per_line(c));
52 void print_cache_properties(char *NT lstring, cache_t *c)
54 printk("%s_WAYS_ASSOCIATIVE: %ld\n", lstring, get_cache_ways_associative(c));
55 printk("%s_LINE_SIZE_BYTES: %ld\n", lstring, get_cache_line_size_bytes(c));
56 printk("%s_SIZE_BYTES: %ld\n", lstring, get_cache_size_bytes(c));
57 printk("%s_SIZE_KILOBYTES: %ld\n", lstring, get_cache_size_kilobytes(c));
58 printk("%s_SIZE_MEGABYTES: %ld\n", lstring, get_cache_size_megabytes(c));
59 printk("%s_OFFSET_BITS: %ld\n", lstring, get_cache_num_offset_bits(c));
60 printk("%s_INDEX_BITS: %ld\n", lstring, get_cache_num_index_bits(c));
61 printk("%s_TAG_BITS: %ld\n", lstring, get_cache_num_tag_bits(c));
62 printk("%s_PAGE_COLOR_BITS: %ld\n", lstring, get_cache_num_page_color_bits(c));
63 printk("%s_BYTES_PER_LINE: %ld\n", lstring, get_cache_bytes_per_line(c));
64 printk("%s_NUM_LINES: %ld\n", lstring, get_cache_num_lines(c));
65 printk("%s_NUM_SETS: %ld\n", lstring, get_cache_num_sets(c));
66 printk("%s_LINES_PER_SET: %ld\n", lstring, get_cache_lines_per_set(c));
67 printk("%s_LINES_PER_PAGE: %ld\n", lstring, get_cache_lines_per_page(c));
68 printk("%s_BYTES_PER_WAY: %ld\n", lstring, get_cache_bytes_per_way(c));
69 printk("%s_LINES_PER_WAY: %ld\n", lstring, get_cache_lines_per_way(c));
70 printk("%s_PAGES_PER_WAY: %ld\n", lstring, get_cache_pages_per_way(c));
71 printk("%s_NUM_PAGE_COLORS: %ld\n", lstring, get_cache_num_page_colors(c));
74 /****************** Cache Properties *********************/
75 inline size_t get_cache_ways_associative(cache_t *c) {
78 inline size_t get_cache_line_size_bytes(cache_t *c) {
81 inline size_t get_cache_size_bytes(cache_t *c) {
82 return (c->sz_k * ONE_KILOBYTE);
84 inline size_t get_cache_size_kilobytes(cache_t *c) {
87 inline size_t get_cache_size_megabytes(cache_t *c) {
88 return (c->sz_k / ONE_KILOBYTE);
90 inline size_t get_cache_num_offset_bits(cache_t *c) {
91 return (LOG2_UP(get_cache_line_size_bytes(c)));
93 inline size_t get_cache_num_index_bits(cache_t *c) {
94 return (LOG2_UP(get_cache_size_bytes(c)
95 / get_cache_ways_associative(c)
96 / get_cache_line_size_bytes(c)));
98 inline size_t get_cache_num_tag_bits(cache_t *c) {
99 return (NUM_ADDR_BITS - get_cache_num_offset_bits(c)
100 - get_cache_num_index_bits(c));
102 inline size_t get_cache_num_page_color_bits(cache_t *c) {
103 return (get_cache_num_offset_bits(c)
104 + get_cache_num_index_bits(c)
107 inline size_t get_cache_bytes_per_line(cache_t *c) {
108 return (1 << get_cache_num_offset_bits(c));
110 inline size_t get_cache_num_lines(cache_t *c) {
111 return (get_cache_size_bytes(c)/get_cache_bytes_per_line(c));
113 inline size_t get_cache_num_sets(cache_t *c) {
114 return (get_cache_num_lines(c)/get_cache_ways_associative(c));
116 inline size_t get_cache_lines_per_set(cache_t *c) {
117 return (get_cache_ways_associative(c));
119 inline size_t get_cache_lines_per_page(cache_t *c) {
120 return (PGSIZE / get_cache_bytes_per_line(c));
122 inline size_t get_cache_bytes_per_way(cache_t *c) {
123 return (get_cache_size_bytes(c)/get_cache_ways_associative(c));
125 inline size_t get_cache_lines_per_way(cache_t *c) {
126 return (get_cache_num_lines(c)/get_cache_ways_associative(c));
128 inline size_t get_cache_pages_per_way(cache_t *c) {
129 return (get_cache_lines_per_way(c)/get_cache_lines_per_page(c));
131 inline size_t get_cache_num_page_colors(cache_t *c) {
132 return get_cache_pages_per_way(c);
135 static inline void set_color_range(uint16_t color, uint8_t* map,
136 cache_t* smaller, cache_t* bigger)
139 if(smaller->num_colors <= bigger->num_colors) {
140 r = bigger->num_colors / smaller->num_colors;
142 SET_BITMASK_RANGE(map, base, base+r);
145 r = smaller->num_colors / bigger->num_colors;
147 if(BITMASK_IS_SET_IN_RANGE(smaller->free_colors_map,
149 SET_BITMASK_BIT(map, base);
153 static inline void clr_color_range(uint16_t color, uint8_t* map,
154 cache_t* smaller, cache_t* bigger)
157 if(smaller->num_colors <= bigger->num_colors) {
158 r = bigger->num_colors / smaller->num_colors;
160 CLR_BITMASK_RANGE(map, base, base+r);
163 r = smaller->num_colors / bigger->num_colors;
165 CLR_BITMASK_BIT(map, base);
169 static inline error_t __cache_color_alloc_specific(size_t color, cache_t* c,
172 if(!GET_BITMASK_BIT(c->free_colors_map, color))
176 clr_color_range(color, l1->free_colors_map, c, l1);
178 clr_color_range(color, l2->free_colors_map, c, l2);
180 clr_color_range(color, l3->free_colors_map, c, l3);
182 set_color_range(color, colors_map, c, llc_cache);
186 static inline error_t __cache_color_alloc(cache_t* c, uint8_t* colors_map)
188 if(BITMASK_IS_CLEAR(c->free_colors_map, c->num_colors))
193 if(GET_BITMASK_BIT(c->free_colors_map, color))
197 return __cache_color_alloc_specific(color, c, colors_map);
200 static inline void __cache_color_free_specific(size_t color, cache_t* c,
203 if(GET_BITMASK_BIT(c->free_colors_map, color))
206 size_t r = llc_cache->num_colors / c->num_colors;
207 size_t base = color*r;
208 if(!BITMASK_IS_SET_IN_RANGE(colors_map, base, base+r))
213 set_color_range(color, l3->free_colors_map, c, l3);
215 set_color_range(color, l2->free_colors_map, c, l2);
217 set_color_range(color, l1->free_colors_map, c, l1);
219 clr_color_range(color, colors_map, c, llc_cache);
222 static inline void __cache_color_free(cache_t* c, uint8_t* colors_map)
224 if(BITMASK_IS_FULL(c->free_colors_map, c->num_colors))
229 if(!GET_BITMASK_BIT(c->free_colors_map, color)) {
230 size_t r = llc_cache->num_colors / c->num_colors;
231 size_t base = color*r;
232 if(BITMASK_IS_SET_IN_RANGE(colors_map, base, base+r))
235 } while(++color < c->num_colors);
236 if(color == c->num_colors)
239 __cache_color_free_specific(color, c, colors_map);
242 uint8_t* cache_colors_map_alloc() {
243 uint8_t* colors_map = kmalloc(llc_cache->num_colors, 0);
245 CLR_BITMASK(colors_map, llc_cache->num_colors);
249 void cache_colors_map_free(uint8_t* colors_map) {
253 error_t cache_color_alloc(cache_t* c, uint8_t* colors_map)
255 spin_lock_irqsave(&cache_colors_lock);
256 error_t e = __cache_color_alloc(c, colors_map);
257 spin_unlock_irqsave(&cache_colors_lock);
260 error_t cache_color_alloc_specific(size_t color, cache_t* c, uint8_t* colors_map)
262 spin_lock_irqsave(&cache_colors_lock);
263 error_t e = __cache_color_alloc_specific(color, c, colors_map);
264 spin_unlock_irqsave(&cache_colors_lock);
268 void cache_color_free(cache_t* c, uint8_t* colors_map)
270 spin_lock_irqsave(&cache_colors_lock);
271 __cache_color_free(c, colors_map);
272 spin_unlock_irqsave(&cache_colors_lock);
274 void cache_color_free_specific(size_t color, cache_t* c, uint8_t* colors_map)
276 spin_lock_irqsave(&cache_colors_lock);
277 __cache_color_free_specific(color, c, colors_map);
278 spin_unlock_irqsave(&cache_colors_lock);