~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/blackfin/mm/sram-alloc.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * SRAM allocator for Blackfin on-chip memory
  3  *
  4  * Copyright 2004-2009 Analog Devices Inc.
  5  *
  6  * Licensed under the GPL-2 or later.
  7  */
  8 
  9 #include <linux/module.h>
 10 #include <linux/kernel.h>
 11 #include <linux/types.h>
 12 #include <linux/miscdevice.h>
 13 #include <linux/ioport.h>
 14 #include <linux/fcntl.h>
 15 #include <linux/init.h>
 16 #include <linux/poll.h>
 17 #include <linux/proc_fs.h>
 18 #include <linux/spinlock.h>
 19 #include <linux/rtc.h>
 20 #include <asm/blackfin.h>
 21 #include <asm/mem_map.h>
 22 #include "blackfin_sram.h"
 23 
 24 /* the data structure for L1 scratchpad and DATA SRAM */
 25 struct sram_piece {
 26         void *paddr;
 27         int size;
 28         pid_t pid;
 29         struct sram_piece *next;
 30 };
 31 
 32 static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock);
 33 static DEFINE_PER_CPU(struct sram_piece, free_l1_ssram_head);
 34 static DEFINE_PER_CPU(struct sram_piece, used_l1_ssram_head);
 35 
 36 #if L1_DATA_A_LENGTH != 0
 37 static DEFINE_PER_CPU(struct sram_piece, free_l1_data_A_sram_head);
 38 static DEFINE_PER_CPU(struct sram_piece, used_l1_data_A_sram_head);
 39 #endif
 40 
 41 #if L1_DATA_B_LENGTH != 0
 42 static DEFINE_PER_CPU(struct sram_piece, free_l1_data_B_sram_head);
 43 static DEFINE_PER_CPU(struct sram_piece, used_l1_data_B_sram_head);
 44 #endif
 45 
 46 #if L1_DATA_A_LENGTH || L1_DATA_B_LENGTH
 47 static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock);
 48 #endif
 49 
 50 #if L1_CODE_LENGTH != 0
 51 static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock);
 52 static DEFINE_PER_CPU(struct sram_piece, free_l1_inst_sram_head);
 53 static DEFINE_PER_CPU(struct sram_piece, used_l1_inst_sram_head);
 54 #endif
 55 
 56 #if L2_LENGTH != 0
 57 static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp;
 58 static struct sram_piece free_l2_sram_head, used_l2_sram_head;
 59 #endif
 60 
 61 static struct kmem_cache *sram_piece_cache;
 62 
 63 /* L1 Scratchpad SRAM initialization function */
 64 static void __init l1sram_init(void)
 65 {
 66         unsigned int cpu;
 67         unsigned long reserve;
 68 
 69 #ifdef CONFIG_SMP
 70         reserve = 0;
 71 #else
 72         reserve = sizeof(struct l1_scratch_task_info);
 73 #endif
 74 
 75         for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
 76                 per_cpu(free_l1_ssram_head, cpu).next =
 77                         kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
 78                 if (!per_cpu(free_l1_ssram_head, cpu).next) {
 79                         printk(KERN_INFO "Fail to initialize Scratchpad data SRAM.\n");
 80                         return;
 81                 }
 82 
 83                 per_cpu(free_l1_ssram_head, cpu).next->paddr = (void *)get_l1_scratch_start_cpu(cpu) + reserve;
 84                 per_cpu(free_l1_ssram_head, cpu).next->size = L1_SCRATCH_LENGTH - reserve;
 85                 per_cpu(free_l1_ssram_head, cpu).next->pid = 0;
 86                 per_cpu(free_l1_ssram_head, cpu).next->next = NULL;
 87 
 88                 per_cpu(used_l1_ssram_head, cpu).next = NULL;
 89 
 90                 /* mutex initialize */
 91                 spin_lock_init(&per_cpu(l1sram_lock, cpu));
 92                 printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n",
 93                         L1_SCRATCH_LENGTH >> 10);
 94         }
 95 }
 96 
 97 static void __init l1_data_sram_init(void)
 98 {
 99 #if L1_DATA_A_LENGTH != 0 || L1_DATA_B_LENGTH != 0
100         unsigned int cpu;
101 #endif
102 #if L1_DATA_A_LENGTH != 0
103         for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
104                 per_cpu(free_l1_data_A_sram_head, cpu).next =
105                         kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
106                 if (!per_cpu(free_l1_data_A_sram_head, cpu).next) {
107                         printk(KERN_INFO "Fail to initialize L1 Data A SRAM.\n");
108                         return;
109                 }
110 
111                 per_cpu(free_l1_data_A_sram_head, cpu).next->paddr =
112                         (void *)get_l1_data_a_start_cpu(cpu) + (_ebss_l1 - _sdata_l1);
113                 per_cpu(free_l1_data_A_sram_head, cpu).next->size =
114                         L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1);
115                 per_cpu(free_l1_data_A_sram_head, cpu).next->pid = 0;
116                 per_cpu(free_l1_data_A_sram_head, cpu).next->next = NULL;
117 
118                 per_cpu(used_l1_data_A_sram_head, cpu).next = NULL;
119 
120                 printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n",
121                         L1_DATA_A_LENGTH >> 10,
122                         per_cpu(free_l1_data_A_sram_head, cpu).next->size >> 10);
123         }
124 #endif
125 #if L1_DATA_B_LENGTH != 0
126         for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
127                 per_cpu(free_l1_data_B_sram_head, cpu).next =
128                         kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
129                 if (!per_cpu(free_l1_data_B_sram_head, cpu).next) {
130                         printk(KERN_INFO "Fail to initialize L1 Data B SRAM.\n");
131                         return;
132                 }
133 
134                 per_cpu(free_l1_data_B_sram_head, cpu).next->paddr =
135                         (void *)get_l1_data_b_start_cpu(cpu) + (_ebss_b_l1 - _sdata_b_l1);
136                 per_cpu(free_l1_data_B_sram_head, cpu).next->size =
137                         L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1);
138                 per_cpu(free_l1_data_B_sram_head, cpu).next->pid = 0;
139                 per_cpu(free_l1_data_B_sram_head, cpu).next->next = NULL;
140 
141                 per_cpu(used_l1_data_B_sram_head, cpu).next = NULL;
142 
143                 printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n",
144                         L1_DATA_B_LENGTH >> 10,
145                         per_cpu(free_l1_data_B_sram_head, cpu).next->size >> 10);
146                 /* mutex initialize */
147         }
148 #endif
149 
150 #if L1_DATA_A_LENGTH != 0 || L1_DATA_B_LENGTH != 0
151         for (cpu = 0; cpu < num_possible_cpus(); ++cpu)
152                 spin_lock_init(&per_cpu(l1_data_sram_lock, cpu));
153 #endif
154 }
155 
156 static void __init l1_inst_sram_init(void)
157 {
158 #if L1_CODE_LENGTH != 0
159         unsigned int cpu;
160         for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
161                 per_cpu(free_l1_inst_sram_head, cpu).next =
162                         kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
163                 if (!per_cpu(free_l1_inst_sram_head, cpu).next) {
164                         printk(KERN_INFO "Failed to initialize L1 Instruction SRAM\n");
165                         return;
166                 }
167 
168                 per_cpu(free_l1_inst_sram_head, cpu).next->paddr =
169                         (void *)get_l1_code_start_cpu(cpu) + (_etext_l1 - _stext_l1);
170                 per_cpu(free_l1_inst_sram_head, cpu).next->size =
171                         L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
172                 per_cpu(free_l1_inst_sram_head, cpu).next->pid = 0;
173                 per_cpu(free_l1_inst_sram_head, cpu).next->next = NULL;
174 
175                 per_cpu(used_l1_inst_sram_head, cpu).next = NULL;
176 
177                 printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n",
178                         L1_CODE_LENGTH >> 10,
179                         per_cpu(free_l1_inst_sram_head, cpu).next->size >> 10);
180 
181                 /* mutex initialize */
182                 spin_lock_init(&per_cpu(l1_inst_sram_lock, cpu));
183         }
184 #endif
185 }
186 
187 static void __init l2_sram_init(void)
188 {
189 #if L2_LENGTH != 0
190         free_l2_sram_head.next =
191                 kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
192         if (!free_l2_sram_head.next) {
193                 printk(KERN_INFO "Fail to initialize L2 SRAM.\n");
194                 return;
195         }
196 
197         free_l2_sram_head.next->paddr =
198                 (void *)L2_START + (_ebss_l2 - _stext_l2);
199         free_l2_sram_head.next->size =
200                 L2_LENGTH - (_ebss_l2 - _stext_l2);
201         free_l2_sram_head.next->pid = 0;
202         free_l2_sram_head.next->next = NULL;
203 
204         used_l2_sram_head.next = NULL;
205 
206         printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n",
207                 L2_LENGTH >> 10,
208                 free_l2_sram_head.next->size >> 10);
209 
210         /* mutex initialize */
211         spin_lock_init(&l2_sram_lock);
212 #endif
213 }
214 
215 static int __init bfin_sram_init(void)
216 {
217         sram_piece_cache = kmem_cache_create("sram_piece_cache",
218                                 sizeof(struct sram_piece),
219                                 0, SLAB_PANIC, NULL);
220 
221         l1sram_init();
222         l1_data_sram_init();
223         l1_inst_sram_init();
224         l2_sram_init();
225 
226         return 0;
227 }
228 pure_initcall(bfin_sram_init);
229 
230 /* SRAM allocate function */
231 static void *_sram_alloc(size_t size, struct sram_piece *pfree_head,
232                 struct sram_piece *pused_head)
233 {
234         struct sram_piece *pslot, *plast, *pavail;
235 
236         if (size <= 0 || !pfree_head || !pused_head)
237                 return NULL;
238 
239         /* Align the size */
240         size = (size + 3) & ~3;
241 
242         pslot = pfree_head->next;
243         plast = pfree_head;
244 
245         /* search an available piece slot */
246         while (pslot != NULL && size > pslot->size) {
247                 plast = pslot;
248                 pslot = pslot->next;
249         }
250 
251         if (!pslot)
252                 return NULL;
253 
254         if (pslot->size == size) {
255                 plast->next = pslot->next;
256                 pavail = pslot;
257         } else {
258                 pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
259 
260                 if (!pavail)
261                         return NULL;
262 
263                 pavail->paddr = pslot->paddr;
264                 pavail->size = size;
265                 pslot->paddr += size;
266                 pslot->size -= size;
267         }
268 
269         pavail->pid = current->pid;
270 
271         pslot = pused_head->next;
272         plast = pused_head;
273 
274         /* insert new piece into used piece list !!! */
275         while (pslot != NULL && pavail->paddr < pslot->paddr) {
276                 plast = pslot;
277                 pslot = pslot->next;
278         }
279 
280         pavail->next = pslot;
281         plast->next = pavail;
282 
283         return pavail->paddr;
284 }
285 
286 /* Allocate the largest available block.  */
287 static void *_sram_alloc_max(struct sram_piece *pfree_head,
288                                 struct sram_piece *pused_head,
289                                 unsigned long *psize)
290 {
291         struct sram_piece *pslot, *pmax;
292 
293         if (!pfree_head || !pused_head)
294                 return NULL;
295 
296         pmax = pslot = pfree_head->next;
297 
298         /* search an available piece slot */
299         while (pslot != NULL) {
300                 if (pslot->size > pmax->size)
301                         pmax = pslot;
302                 pslot = pslot->next;
303         }
304 
305         if (!pmax)
306                 return NULL;
307 
308         *psize = pmax->size;
309 
310         return _sram_alloc(*psize, pfree_head, pused_head);
311 }
312 
313 /* SRAM free function */
314 static int _sram_free(const void *addr,
315                         struct sram_piece *pfree_head,
316                         struct sram_piece *pused_head)
317 {
318         struct sram_piece *pslot, *plast, *pavail;
319 
320         if (!pfree_head || !pused_head)
321                 return -1;
322 
323         /* search the relevant memory slot */
324         pslot = pused_head->next;
325         plast = pused_head;
326 
327         /* search an available piece slot */
328         while (pslot != NULL && pslot->paddr != addr) {
329                 plast = pslot;
330                 pslot = pslot->next;
331         }
332 
333         if (!pslot)
334                 return -1;
335 
336         plast->next = pslot->next;
337         pavail = pslot;
338         pavail->pid = 0;
339 
340         /* insert free pieces back to the free list */
341         pslot = pfree_head->next;
342         plast = pfree_head;
343 
344         while (pslot != NULL && addr > pslot->paddr) {
345                 plast = pslot;
346                 pslot = pslot->next;
347         }
348 
349         if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) {
350                 plast->size += pavail->size;
351                 kmem_cache_free(sram_piece_cache, pavail);
352         } else {
353                 pavail->next = plast->next;
354                 plast->next = pavail;
355                 plast = pavail;
356         }
357 
358         if (pslot && plast->paddr + plast->size == pslot->paddr) {
359                 plast->size += pslot->size;
360                 plast->next = pslot->next;
361                 kmem_cache_free(sram_piece_cache, pslot);
362         }
363 
364         return 0;
365 }
366 
367 int sram_free(const void *addr)
368 {
369 
370 #if L1_CODE_LENGTH != 0
371         if (addr >= (void *)get_l1_code_start()
372                  && addr < (void *)(get_l1_code_start() + L1_CODE_LENGTH))
373                 return l1_inst_sram_free(addr);
374         else
375 #endif
376 #if L1_DATA_A_LENGTH != 0
377         if (addr >= (void *)get_l1_data_a_start()
378                  && addr < (void *)(get_l1_data_a_start() + L1_DATA_A_LENGTH))
379                 return l1_data_A_sram_free(addr);
380         else
381 #endif
382 #if L1_DATA_B_LENGTH != 0
383         if (addr >= (void *)get_l1_data_b_start()
384                  && addr < (void *)(get_l1_data_b_start() + L1_DATA_B_LENGTH))
385                 return l1_data_B_sram_free(addr);
386         else
387 #endif
388 #if L2_LENGTH != 0
389         if (addr >= (void *)L2_START
390                  && addr < (void *)(L2_START + L2_LENGTH))
391                 return l2_sram_free(addr);
392         else
393 #endif
394                 return -1;
395 }
396 EXPORT_SYMBOL(sram_free);
397 
398 void *l1_data_A_sram_alloc(size_t size)
399 {
400 #if L1_DATA_A_LENGTH != 0
401         unsigned long flags;
402         void *addr;
403         unsigned int cpu;
404 
405         cpu = get_cpu();
406         /* add mutex operation */
407         spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
408 
409         addr = _sram_alloc(size, &per_cpu(free_l1_data_A_sram_head, cpu),
410                         &per_cpu(used_l1_data_A_sram_head, cpu));
411 
412         /* add mutex operation */
413         spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
414         put_cpu();
415 
416         pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
417                  (long unsigned int)addr, size);
418 
419         return addr;
420 #else
421         return NULL;
422 #endif
423 }
424 EXPORT_SYMBOL(l1_data_A_sram_alloc);
425 
426 int l1_data_A_sram_free(const void *addr)
427 {
428 #if L1_DATA_A_LENGTH != 0
429         unsigned long flags;
430         int ret;
431         unsigned int cpu;
432 
433         cpu = get_cpu();
434         /* add mutex operation */
435         spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
436 
437         ret = _sram_free(addr, &per_cpu(free_l1_data_A_sram_head, cpu),
438                         &per_cpu(used_l1_data_A_sram_head, cpu));
439 
440         /* add mutex operation */
441         spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
442         put_cpu();
443 
444         return ret;
445 #else
446         return -1;
447 #endif
448 }
449 EXPORT_SYMBOL(l1_data_A_sram_free);
450 
451 void *l1_data_B_sram_alloc(size_t size)
452 {
453 #if L1_DATA_B_LENGTH != 0
454         unsigned long flags;
455         void *addr;
456         unsigned int cpu;
457 
458         cpu = get_cpu();
459         /* add mutex operation */
460         spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
461 
462         addr = _sram_alloc(size, &per_cpu(free_l1_data_B_sram_head, cpu),
463                         &per_cpu(used_l1_data_B_sram_head, cpu));
464 
465         /* add mutex operation */
466         spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
467         put_cpu();
468 
469         pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
470                  (long unsigned int)addr, size);
471 
472         return addr;
473 #else
474         return NULL;
475 #endif
476 }
477 EXPORT_SYMBOL(l1_data_B_sram_alloc);
478 
479 int l1_data_B_sram_free(const void *addr)
480 {
481 #if L1_DATA_B_LENGTH != 0
482         unsigned long flags;
483         int ret;
484         unsigned int cpu;
485 
486         cpu = get_cpu();
487         /* add mutex operation */
488         spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
489 
490         ret = _sram_free(addr, &per_cpu(free_l1_data_B_sram_head, cpu),
491                         &per_cpu(used_l1_data_B_sram_head, cpu));
492 
493         /* add mutex operation */
494         spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
495         put_cpu();
496 
497         return ret;
498 #else
499         return -1;
500 #endif
501 }
502 EXPORT_SYMBOL(l1_data_B_sram_free);
503 
504 void *l1_data_sram_alloc(size_t size)
505 {
506         void *addr = l1_data_A_sram_alloc(size);
507 
508         if (!addr)
509                 addr = l1_data_B_sram_alloc(size);
510 
511         return addr;
512 }
513 EXPORT_SYMBOL(l1_data_sram_alloc);
514 
515 void *l1_data_sram_zalloc(size_t size)
516 {
517         void *addr = l1_data_sram_alloc(size);
518 
519         if (addr)
520                 memset(addr, 0x00, size);
521 
522         return addr;
523 }
524 EXPORT_SYMBOL(l1_data_sram_zalloc);
525 
526 int l1_data_sram_free(const void *addr)
527 {
528         int ret;
529         ret = l1_data_A_sram_free(addr);
530         if (ret == -1)
531                 ret = l1_data_B_sram_free(addr);
532         return ret;
533 }
534 EXPORT_SYMBOL(l1_data_sram_free);
535 
536 void *l1_inst_sram_alloc(size_t size)
537 {
538 #if L1_CODE_LENGTH != 0
539         unsigned long flags;
540         void *addr;
541         unsigned int cpu;
542 
543         cpu = get_cpu();
544         /* add mutex operation */
545         spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
546 
547         addr = _sram_alloc(size, &per_cpu(free_l1_inst_sram_head, cpu),
548                         &per_cpu(used_l1_inst_sram_head, cpu));
549 
550         /* add mutex operation */
551         spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
552         put_cpu();
553 
554         pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
555                  (long unsigned int)addr, size);
556 
557         return addr;
558 #else
559         return NULL;
560 #endif
561 }
562 EXPORT_SYMBOL(l1_inst_sram_alloc);
563 
564 int l1_inst_sram_free(const void *addr)
565 {
566 #if L1_CODE_LENGTH != 0
567         unsigned long flags;
568         int ret;
569         unsigned int cpu;
570 
571         cpu = get_cpu();
572         /* add mutex operation */
573         spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
574 
575         ret = _sram_free(addr, &per_cpu(free_l1_inst_sram_head, cpu),
576                         &per_cpu(used_l1_inst_sram_head, cpu));
577 
578         /* add mutex operation */
579         spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
580         put_cpu();
581 
582         return ret;
583 #else
584         return -1;
585 #endif
586 }
587 EXPORT_SYMBOL(l1_inst_sram_free);
588 
589 /* L1 Scratchpad memory allocate function */
590 void *l1sram_alloc(size_t size)
591 {
592         unsigned long flags;
593         void *addr;
594         unsigned int cpu;
595 
596         cpu = get_cpu();
597         /* add mutex operation */
598         spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
599 
600         addr = _sram_alloc(size, &per_cpu(free_l1_ssram_head, cpu),
601                         &per_cpu(used_l1_ssram_head, cpu));
602 
603         /* add mutex operation */
604         spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
605         put_cpu();
606 
607         return addr;
608 }
609 
610 /* L1 Scratchpad memory allocate function */
611 void *l1sram_alloc_max(size_t *psize)
612 {
613         unsigned long flags;
614         void *addr;
615         unsigned int cpu;
616 
617         cpu = get_cpu();
618         /* add mutex operation */
619         spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
620 
621         addr = _sram_alloc_max(&per_cpu(free_l1_ssram_head, cpu),
622                         &per_cpu(used_l1_ssram_head, cpu), psize);
623 
624         /* add mutex operation */
625         spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
626         put_cpu();
627 
628         return addr;
629 }
630 
631 /* L1 Scratchpad memory free function */
632 int l1sram_free(const void *addr)
633 {
634         unsigned long flags;
635         int ret;
636         unsigned int cpu;
637 
638         cpu = get_cpu();
639         /* add mutex operation */
640         spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
641 
642         ret = _sram_free(addr, &per_cpu(free_l1_ssram_head, cpu),
643                         &per_cpu(used_l1_ssram_head, cpu));
644 
645         /* add mutex operation */
646         spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
647         put_cpu();
648 
649         return ret;
650 }
651 
652 void *l2_sram_alloc(size_t size)
653 {
654 #if L2_LENGTH != 0
655         unsigned long flags;
656         void *addr;
657 
658         /* add mutex operation */
659         spin_lock_irqsave(&l2_sram_lock, flags);
660 
661         addr = _sram_alloc(size, &free_l2_sram_head,
662                         &used_l2_sram_head);
663 
664         /* add mutex operation */
665         spin_unlock_irqrestore(&l2_sram_lock, flags);
666 
667         pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n",
668                  (long unsigned int)addr, size);
669 
670         return addr;
671 #else
672         return NULL;
673 #endif
674 }
675 EXPORT_SYMBOL(l2_sram_alloc);
676 
677 void *l2_sram_zalloc(size_t size)
678 {
679         void *addr = l2_sram_alloc(size);
680 
681         if (addr)
682                 memset(addr, 0x00, size);
683 
684         return addr;
685 }
686 EXPORT_SYMBOL(l2_sram_zalloc);
687 
688 int l2_sram_free(const void *addr)
689 {
690 #if L2_LENGTH != 0
691         unsigned long flags;
692         int ret;
693 
694         /* add mutex operation */
695         spin_lock_irqsave(&l2_sram_lock, flags);
696 
697         ret = _sram_free(addr, &free_l2_sram_head,
698                         &used_l2_sram_head);
699 
700         /* add mutex operation */
701         spin_unlock_irqrestore(&l2_sram_lock, flags);
702 
703         return ret;
704 #else
705         return -1;
706 #endif
707 }
708 EXPORT_SYMBOL(l2_sram_free);
709 
710 int sram_free_with_lsl(const void *addr)
711 {
712         struct sram_list_struct *lsl, **tmp;
713         struct mm_struct *mm = current->mm;
714 
715         for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next)
716                 if ((*tmp)->addr == addr)
717                         goto found;
718         return -1;
719 found:
720         lsl = *tmp;
721         sram_free(addr);
722         *tmp = lsl->next;
723         kfree(lsl);
724 
725         return 0;
726 }
727 EXPORT_SYMBOL(sram_free_with_lsl);
728 
729 /* Allocate memory and keep in L1 SRAM List (lsl) so that the resources are
730  * tracked.  These are designed for userspace so that when a process exits,
731  * we can safely reap their resources.
732  */
733 void *sram_alloc_with_lsl(size_t size, unsigned long flags)
734 {
735         void *addr = NULL;
736         struct sram_list_struct *lsl = NULL;
737         struct mm_struct *mm = current->mm;
738 
739         lsl = kzalloc(sizeof(struct sram_list_struct), GFP_KERNEL);
740         if (!lsl)
741                 return NULL;
742 
743         if (flags & L1_INST_SRAM)
744                 addr = l1_inst_sram_alloc(size);
745 
746         if (addr == NULL && (flags & L1_DATA_A_SRAM))
747                 addr = l1_data_A_sram_alloc(size);
748 
749         if (addr == NULL && (flags & L1_DATA_B_SRAM))
750                 addr = l1_data_B_sram_alloc(size);
751 
752         if (addr == NULL && (flags & L2_SRAM))
753                 addr = l2_sram_alloc(size);
754 
755         if (addr == NULL) {
756                 kfree(lsl);
757                 return NULL;
758         }
759         lsl->addr = addr;
760         lsl->length = size;
761         lsl->next = mm->context.sram_list;
762         mm->context.sram_list = lsl;
763         return addr;
764 }
765 EXPORT_SYMBOL(sram_alloc_with_lsl);
766 
767 #ifdef CONFIG_PROC_FS
768 /* Once we get a real allocator, we'll throw all of this away.
769  * Until then, we need some sort of visibility into the L1 alloc.
770  */
771 /* Need to keep line of output the same.  Currently, that is 44 bytes
772  * (including newline).
773  */
774 static int _sram_proc_read(char *buf, int *len, int count, const char *desc,
775                 struct sram_piece *pfree_head,
776                 struct sram_piece *pused_head)
777 {
778         struct sram_piece *pslot;
779 
780         if (!pfree_head || !pused_head)
781                 return -1;
782 
783         *len += sprintf(&buf[*len], "--- SRAM %-14s Size   PID State     \n", desc);
784 
785         /* search the relevant memory slot */
786         pslot = pused_head->next;
787 
788         while (pslot != NULL) {
789                 *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
790                         pslot->paddr, pslot->paddr + pslot->size,
791                         pslot->size, pslot->pid, "ALLOCATED");
792 
793                 pslot = pslot->next;
794         }
795 
796         pslot = pfree_head->next;
797 
798         while (pslot != NULL) {
799                 *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
800                         pslot->paddr, pslot->paddr + pslot->size,
801                         pslot->size, pslot->pid, "FREE");
802 
803                 pslot = pslot->next;
804         }
805 
806         return 0;
807 }
808 static int sram_proc_read(char *buf, char **start, off_t offset, int count,
809                 int *eof, void *data)
810 {
811         int len = 0;
812         unsigned int cpu;
813 
814         for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
815                 if (_sram_proc_read(buf, &len, count, "Scratchpad",
816                         &per_cpu(free_l1_ssram_head, cpu), &per_cpu(used_l1_ssram_head, cpu)))
817                         goto not_done;
818 #if L1_DATA_A_LENGTH != 0
819                 if (_sram_proc_read(buf, &len, count, "L1 Data A",
820                         &per_cpu(free_l1_data_A_sram_head, cpu),
821                         &per_cpu(used_l1_data_A_sram_head, cpu)))
822                         goto not_done;
823 #endif
824 #if L1_DATA_B_LENGTH != 0
825                 if (_sram_proc_read(buf, &len, count, "L1 Data B",
826                         &per_cpu(free_l1_data_B_sram_head, cpu),
827                         &per_cpu(used_l1_data_B_sram_head, cpu)))
828                         goto not_done;
829 #endif
830 #if L1_CODE_LENGTH != 0
831                 if (_sram_proc_read(buf, &len, count, "L1 Instruction",
832                         &per_cpu(free_l1_inst_sram_head, cpu),
833                         &per_cpu(used_l1_inst_sram_head, cpu)))
834                         goto not_done;
835 #endif
836         }
837 #if L2_LENGTH != 0
838         if (_sram_proc_read(buf, &len, count, "L2", &free_l2_sram_head,
839                 &used_l2_sram_head))
840                 goto not_done;
841 #endif
842         *eof = 1;
843  not_done:
844         return len;
845 }
846 
847 static int __init sram_proc_init(void)
848 {
849         struct proc_dir_entry *ptr;
850         ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL);
851         if (!ptr) {
852                 printk(KERN_WARNING "unable to create /proc/sram\n");
853                 return -1;
854         }
855         ptr->read_proc = sram_proc_read;
856         return 0;
857 }
858 late_initcall(sram_proc_init);
859 #endif
860 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp