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