From 260d5d3517c67c5b68b4e28c5d3e1e3b73976a90 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 16:34:05 +0800 Subject: Blackfin arch: Fix bug - do not overflow the buffer given to us which tends to happen when CONFIG_L1_MAX_PIECE is increased past its default Singed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mm/blackfin_sram.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'arch/blackfin/mm') diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index 3246f91c7baa..8f6fdc245330 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -549,13 +549,16 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); /* Once we get a real allocator, we'll throw all of this away. * Until then, we need some sort of visibility into the L1 alloc. */ -static void _l1sram_proc_read(char *buf, int *len, const char *desc, +/* Need to keep line of output the same. Currently, that is 44 bytes + * (including newline). + */ +static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, struct l1_sram_piece *pfree, const int array_size) { int i; - *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State\n", desc); - for (i = 0; i < array_size; ++i) { + *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); + for (i = 0; i < array_size && *len < count; ++i) { const char *alloc_type; switch (pfree[i].flag) { case SRAM_SLT_NULL: alloc_type = "NULL"; break; @@ -563,31 +566,42 @@ static void _l1sram_proc_read(char *buf, int *len, const char *desc, case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; default: alloc_type = "????"; break; } - *len += sprintf(&buf[*len], "%p-%p %8i %4i %s\n", + /* if we've got a lot of space to cover, omit things */ + if ((PAGE_SIZE - 1024) < (CONFIG_L1_MAX_PIECE + 1) * 4 * 44 && + pfree[i].size == 0) + continue; + *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", pfree[i].paddr, pfree[i].paddr + pfree[i].size, pfree[i].size, pfree[i].pid, alloc_type); } + return (i != array_size); } static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len = 0; - _l1sram_proc_read(buf, &len, "Scratchpad", - l1_ssram, ARRAY_SIZE(l1_ssram)); + if (_l1sram_proc_read(buf, &len, count, "Scratchpad", + l1_ssram, ARRAY_SIZE(l1_ssram))) + goto not_done; #if L1_DATA_A_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Data A", - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + if (_l1sram_proc_read(buf, &len, count, "Data A", + l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram))) + goto not_done; #endif #if L1_DATA_B_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Data B", - l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + if (_l1sram_proc_read(buf, &len, count, "Data B", + l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram))) + goto not_done; #endif #if L1_CODE_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Instruction", - l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + if (_l1sram_proc_read(buf, &len, count, "Instruction", + l1_inst_sram, ARRAY_SIZE(l1_inst_sram))) + goto not_done; #endif + *eof = 1; + not_done: return len; } -- cgit v1.2.3-59-g8ed1b From 5d481f497559245ecfb1b95cafe39bfbf037fda5 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 19 Jul 2008 14:51:31 +0800 Subject: Blackfin arch: change L1 malloc to base on slab cache and lists. Remove the sram piece limitation and improve the performance to alloc/free sram piece data. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/mm/blackfin_sram.c | 395 +++++++++++++++++++++++---------------- arch/blackfin/mm/blackfin_sram.h | 4 +- arch/blackfin/mm/init.c | 12 +- 3 files changed, 248 insertions(+), 163 deletions(-) (limited to 'arch/blackfin/mm') diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index 8f6fdc245330..b58cf196d7cc 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -41,215 +41,276 @@ #include #include "blackfin_sram.h" -spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; - -#if CONFIG_L1_MAX_PIECE < 16 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 16 -#endif - -#if CONFIG_L1_MAX_PIECE > 1024 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 1024 -#endif - -#define SRAM_SLT_NULL 0 -#define SRAM_SLT_FREE 1 -#define SRAM_SLT_ALLOCATED 2 +static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; /* the data structure for L1 scratchpad and DATA SRAM */ -struct l1_sram_piece { +struct sram_piece { void *paddr; int size; - int flag; pid_t pid; + struct sram_piece *next; }; -static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_ssram_head, used_l1_ssram_head; #if L1_DATA_A_LENGTH != 0 -static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head; #endif #if L1_DATA_B_LENGTH != 0 -static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; #endif #if L1_CODE_LENGTH != 0 -static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; #endif +static struct kmem_cache *sram_piece_cache; + /* L1 Scratchpad SRAM initialization function */ -void __init l1sram_init(void) +static void __init l1sram_init(void) { - printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", - L1_SCRATCH_LENGTH >> 10); + free_l1_ssram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_ssram_head.next) { + printk(KERN_INFO"Fail to initialize Scratchpad data SRAM.\n"); + return; + } - memset(&l1_ssram, 0x00, sizeof(l1_ssram)); - l1_ssram[0].paddr = (void *)L1_SCRATCH_START; - l1_ssram[0].size = L1_SCRATCH_LENGTH; - l1_ssram[0].flag = SRAM_SLT_FREE; + free_l1_ssram_head.next->paddr = (void *)L1_SCRATCH_START; + free_l1_ssram_head.next->size = L1_SCRATCH_LENGTH; + free_l1_ssram_head.next->pid = 0; + free_l1_ssram_head.next->next = NULL; + + used_l1_ssram_head.next = NULL; /* mutex initialize */ spin_lock_init(&l1sram_lock); + + printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", + L1_SCRATCH_LENGTH >> 10); } -void __init l1_data_sram_init(void) +static void __init l1_data_sram_init(void) { #if L1_DATA_A_LENGTH != 0 - memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); - l1_data_A_sram[0].paddr = (void *)L1_DATA_A_START + - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].flag = SRAM_SLT_FREE; + free_l1_data_A_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_data_A_sram_head.next) { + printk(KERN_INFO"Fail to initialize Data A SRAM.\n"); + return; + } + + free_l1_data_A_sram_head.next->paddr = + (void *)L1_DATA_A_START + (_ebss_l1 - _sdata_l1); + free_l1_data_A_sram_head.next->size = + L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); + free_l1_data_A_sram_head.next->pid = 0; + free_l1_data_A_sram_head.next->next = NULL; + + used_l1_data_A_sram_head.next = NULL; printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", - L1_DATA_A_LENGTH >> 10, l1_data_A_sram[0].size >> 10); + L1_DATA_A_LENGTH >> 10, + free_l1_data_A_sram_head.next->size >> 10); #endif #if L1_DATA_B_LENGTH != 0 - memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); - l1_data_B_sram[0].paddr = (void *)L1_DATA_B_START + - (_ebss_b_l1 - _sdata_b_l1); - l1_data_B_sram[0].size = L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); - l1_data_B_sram[0].flag = SRAM_SLT_FREE; + free_l1_data_B_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_data_B_sram_head.next) { + printk(KERN_INFO"Fail to initialize Data B SRAM.\n"); + return; + } + + free_l1_data_B_sram_head.next->paddr = + (void *)L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1); + free_l1_data_B_sram_head.next->size = + L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); + free_l1_data_B_sram_head.next->pid = 0; + free_l1_data_B_sram_head.next->next = NULL; + + used_l1_data_B_sram_head.next = NULL; printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", - L1_DATA_B_LENGTH >> 10, l1_data_B_sram[0].size >> 10); + L1_DATA_B_LENGTH >> 10, + free_l1_data_B_sram_head.next->size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_data_sram_lock); } -void __init l1_inst_sram_init(void) +static void __init l1_inst_sram_init(void) { #if L1_CODE_LENGTH != 0 - memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); - l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1); - l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); - l1_inst_sram[0].flag = SRAM_SLT_FREE; + free_l1_inst_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_inst_sram_head.next) { + printk(KERN_INFO"Fail to initialize Instruction SRAM.\n"); + return; + } + + free_l1_inst_sram_head.next->paddr = + (void *)L1_CODE_START + (_etext_l1 - _stext_l1); + free_l1_inst_sram_head.next->size = + L1_CODE_LENGTH - (_etext_l1 - _stext_l1); + free_l1_inst_sram_head.next->pid = 0; + free_l1_inst_sram_head.next->next = NULL; + + used_l1_inst_sram_head.next = NULL; printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", - L1_CODE_LENGTH >> 10, l1_inst_sram[0].size >> 10); + L1_CODE_LENGTH >> 10, + free_l1_inst_sram_head.next->size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_inst_sram_lock); } +void __init bfin_sram_init(void) +{ + sram_piece_cache = kmem_cache_create("sram_piece_cache", + sizeof(struct sram_piece), + 0, SLAB_PANIC, NULL); + + l1sram_init(); + l1_data_sram_init(); + l1_inst_sram_init(); +} + /* L1 memory allocate function */ -static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) +static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, + struct sram_piece *pused_head) { - int i, index = 0; - void *addr = NULL; + struct sram_piece *pslot, *plast, *pavail; - if (size <= 0) + if (size <= 0 || !pfree_head || !pused_head) return NULL; /* Align the size */ size = (size + 3) & ~3; - /* not use the good method to match the best slot !!! */ - /* search an available memory slot */ - for (i = 0; i < count; i++) { - if ((pfree[i].flag == SRAM_SLT_FREE) - && (pfree[i].size >= size)) { - addr = pfree[i].paddr; - pfree[i].flag = SRAM_SLT_ALLOCATED; - pfree[i].pid = current->pid; - index = i; - break; - } + pslot = pfree_head->next; + plast = pfree_head; + + /* search an available piece slot */ + while (pslot != NULL && size > pslot->size) { + plast = pslot; + pslot = pslot->next; } - if (i >= count) + + if (!pslot) return NULL; - /* updated the NULL memory slot !!! */ - if (pfree[i].size > size) { - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_NULL) { - pfree[i].pid = 0; - pfree[i].flag = SRAM_SLT_FREE; - pfree[i].paddr = addr + size; - pfree[i].size = pfree[index].size - size; - pfree[index].size = size; - break; - } - } + if (pslot->size == size) { + plast->next = pslot->next; + pavail = pslot; + } else { + pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + + if (!pavail) + return NULL; + + pavail->paddr = pslot->paddr; + pavail->size = size; + pslot->paddr += size; + pslot->size -= size; } - return addr; + pavail->pid = current->pid; + + pslot = pused_head->next; + plast = pused_head; + + /* insert new piece into used piece list !!! */ + while (pslot != NULL && pavail->paddr < pslot->paddr) { + plast = pslot; + pslot = pslot->next; + } + + pavail->next = pslot; + plast->next = pavail; + + return pavail->paddr; } /* Allocate the largest available block. */ -static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, +static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, + struct sram_piece *pused_head, unsigned long *psize) { - unsigned long best = 0; - int i, index = -1; - void *addr = NULL; + struct sram_piece *pslot, *pmax; + + if (!pfree_head || !pused_head) + return NULL; + + pmax = pslot = pfree_head->next; - /* search an available memory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { - addr = pfree[i].paddr; - index = i; - best = pfree[i].size; - } + /* search an available piece slot */ + while (pslot != NULL) { + if (pslot->size > pmax->size) + pmax = pslot; + pslot = pslot->next; } - if (index < 0) + + if (!pmax) return NULL; - *psize = best; - pfree[index].pid = current->pid; - pfree[index].flag = SRAM_SLT_ALLOCATED; - return addr; + *psize = pmax->size; + + return _l1_sram_alloc(*psize, pfree_head, pused_head); } /* L1 memory free function */ static int _l1_sram_free(const void *addr, - struct l1_sram_piece *pfree, - int count) + struct sram_piece *pfree_head, + struct sram_piece *pused_head) { - int i, index = 0; + struct sram_piece *pslot, *plast, *pavail; + + if (!pfree_head || !pused_head) + return -1; /* search the relevant memory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].paddr == addr) { - if (pfree[i].flag != SRAM_SLT_ALLOCATED) { - /* error log */ - return -1; - } - index = i; - break; - } + pslot = pused_head->next; + plast = pused_head; + + /* search an available piece slot */ + while (pslot != NULL && pslot->paddr != addr) { + plast = pslot; + pslot = pslot->next; } - if (i >= count) + + if (!pslot) return -1; - pfree[index].pid = 0; - pfree[index].flag = SRAM_SLT_FREE; - - /* link the next address slot */ - for (i = 0; i < count; i++) { - if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) - && (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[i].pid = 0; - pfree[i].flag = SRAM_SLT_NULL; - pfree[index].size += pfree[i].size; - pfree[index].flag = SRAM_SLT_FREE; - break; - } + plast->next = pslot->next; + pavail = pslot; + pavail->pid = 0; + + /* insert free pieces back to the free list */ + pslot = pfree_head->next; + plast = pfree_head; + + while (pslot != NULL && addr > pslot->paddr) { + plast = pslot; + pslot = pslot->next; + } + + if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) { + plast->size += pavail->size; + kmem_cache_free(sram_piece_cache, pavail); + } else { + pavail->next = plast; + plast->next = pavail; + plast = pavail; } - /* link the last address slot */ - for (i = 0; i < count; i++) { - if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && - (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[index].flag = SRAM_SLT_NULL; - pfree[i].size += pfree[index].size; - break; - } + if (pslot && plast->paddr + plast->size == pslot->paddr) { + plast->size += pslot->size; + plast->next = pslot->next; + kmem_cache_free(sram_piece_cache, pslot); } return 0; @@ -287,7 +348,8 @@ void *l1_data_A_sram_alloc(size_t size) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + addr = _l1_sram_alloc(size, &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head); #endif /* add mutex operation */ @@ -309,8 +371,8 @@ int l1_data_A_sram_free(const void *addr) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - ret = _l1_sram_free(addr, - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + ret = _l1_sram_free(addr, &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head); #else ret = -1; #endif @@ -331,7 +393,8 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + addr = _l1_sram_alloc(size, &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -355,7 +418,8 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + ret = _l1_sram_free(addr, &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -408,7 +472,8 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + addr = _l1_sram_alloc(size, &free_l1_inst_sram_head, + &used_l1_inst_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -432,7 +497,8 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + ret = _l1_sram_free(addr, &free_l1_inst_sram_head, + &used_l1_inst_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -453,7 +519,8 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); + addr = _l1_sram_alloc(size, &free_l1_ssram_head, + &used_l1_ssram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -470,7 +537,8 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); + addr = _l1_sram_alloc_max(&free_l1_ssram_head, + &used_l1_ssram_head, psize); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -487,7 +555,8 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); + ret = _l1_sram_free(addr, &free_l1_ssram_head, + &used_l1_ssram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -553,28 +622,38 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); * (including newline). */ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, - struct l1_sram_piece *pfree, const int array_size) + struct sram_piece *pfree_head, + struct sram_piece *pused_head) { - int i; + struct sram_piece *pslot; + + if (!pfree_head || !pused_head) + return -1; *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); - for (i = 0; i < array_size && *len < count; ++i) { - const char *alloc_type; - switch (pfree[i].flag) { - case SRAM_SLT_NULL: alloc_type = "NULL"; break; - case SRAM_SLT_FREE: alloc_type = "FREE"; break; - case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; - default: alloc_type = "????"; break; - } - /* if we've got a lot of space to cover, omit things */ - if ((PAGE_SIZE - 1024) < (CONFIG_L1_MAX_PIECE + 1) * 4 * 44 && - pfree[i].size == 0) - continue; + + /* search the relevant memory slot */ + pslot = pused_head->next; + + while (pslot != NULL) { *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", - pfree[i].paddr, pfree[i].paddr + pfree[i].size, - pfree[i].size, pfree[i].pid, alloc_type); + pslot->paddr, pslot->paddr + pslot->size, + pslot->size, pslot->pid, "ALLOCATED"); + + pslot = pslot->next; + } + + pslot = pfree_head->next; + + while (pslot != NULL) { + *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + pslot->paddr, pslot->paddr + pslot->size, + pslot->size, pslot->pid, "FREE"); + + pslot = pslot->next; } - return (i != array_size); + + return 0; } static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) @@ -582,21 +661,23 @@ static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int len = 0; if (_l1sram_proc_read(buf, &len, count, "Scratchpad", - l1_ssram, ARRAY_SIZE(l1_ssram))) + &free_l1_ssram_head, &used_l1_ssram_head)) goto not_done; #if L1_DATA_A_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Data A", - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram))) + &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head)) goto not_done; #endif #if L1_DATA_B_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Data B", - l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram))) + &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head)) goto not_done; #endif #if L1_CODE_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Instruction", - l1_inst_sram, ARRAY_SIZE(l1_inst_sram))) + &free_l1_inst_sram_head, &used_l1_inst_sram_head)) goto not_done; #endif diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h index 0fb73b78dd60..8cb0945563f9 100644 --- a/arch/blackfin/mm/blackfin_sram.h +++ b/arch/blackfin/mm/blackfin_sram.h @@ -30,9 +30,7 @@ #ifndef __BLACKFIN_SRAM_H__ #define __BLACKFIN_SRAM_H__ -extern void l1sram_init(void); -extern void l1_inst_sram_init(void); -extern void l1_data_sram_init(void); +extern void bfin_sram_init(void); extern void *l1sram_alloc(size_t); #endif diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index ec3141fefd20..4aab21f44096 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -164,11 +164,14 @@ void __init mem_init(void) "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); +} + +static int __init sram_init(void) +{ + unsigned long tmp; /* Initialize the blackfin L1 Memory. */ - l1sram_init(); - l1_data_sram_init(); - l1_inst_sram_init(); + bfin_sram_init(); /* Allocate this once; never free it. We assume this gives us a pointer to the start of L1 scratchpad memory; panic if it @@ -179,7 +182,10 @@ void __init mem_init(void) tmp, (unsigned long)L1_SCRATCH_TASK_INFO); panic("No L1, time to give up\n"); } + + return 0; } +pure_initcall(sram_init); static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { -- cgit v1.2.3-59-g8ed1b From 262c3825a9f3eb0f4f30ebb4b1ee57397bcb3ffc Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 19 Jul 2008 15:42:41 +0800 Subject: Blackfin arch: Extend sram malloc to handle L2 SRAM. Extend system call to alloc L2 SRAM in application. Automatically move following sections to L2 SRAM: 1. kernel built-in l2 attribute section 2. kernel module l2 attribute section 3. elf-fdpic application l2 attribute section Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/kernel/module.c | 74 ++++++++++++---- arch/blackfin/kernel/setup.c | 10 +++ arch/blackfin/kernel/vmlinux.lds.S | 40 +++++++-- arch/blackfin/mm/blackfin_sram.c | 170 ++++++++++++++++++++++++++++++------- include/asm-blackfin/bfin-global.h | 8 +- include/asm-blackfin/elf.h | 2 + include/asm-blackfin/module.h | 5 +- 7 files changed, 253 insertions(+), 56 deletions(-) (limited to 'arch/blackfin/mm') diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 14a42848f37f..e1bebc80a5bf 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -173,7 +173,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, for (s = sechdrs; s < sechdrs_end; ++s) { if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { @@ -188,7 +188,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { @@ -203,7 +203,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { @@ -242,6 +242,51 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_flags &= ~SHF_ALLOC; s->sh_addr = (unsigned long)dest; } + if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || + ((strcmp(".text", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.text_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || + ((strcmp(".data", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.data_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || + ((strcmp(".bss", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.bss_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memset(dest, 0, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } } return 0; } @@ -411,9 +456,10 @@ module_finalize(const Elf_Ehdr * hdr, continue; if ((sechdrs[i].sh_type == SHT_RELA) && - ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || + ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || + (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && - (hdr->e_flags & FLG_CODE_IN_L1)))) { + (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { apply_relocate_add((Elf_Shdr *) sechdrs, strtab, symindex, i, mod); } @@ -423,14 +469,12 @@ module_finalize(const Elf_Ehdr * hdr, void module_arch_cleanup(struct module *mod) { - if (mod->arch.text_l1) - l1_inst_sram_free((void *)mod->arch.text_l1); - if (mod->arch.data_a_l1) - l1_data_sram_free((void *)mod->arch.data_a_l1); - if (mod->arch.bss_a_l1) - l1_data_sram_free((void *)mod->arch.bss_a_l1); - if (mod->arch.data_b_l1) - l1_data_B_sram_free((void *)mod->arch.data_b_l1); - if (mod->arch.bss_b_l1) - l1_data_B_sram_free((void *)mod->arch.bss_b_l1); + l1_inst_sram_free(mod->arch.text_l1); + l1_data_A_sram_free(mod->arch.data_a_l1); + l1_data_A_sram_free(mod->arch.bss_a_l1); + l1_data_B_sram_free(mod->arch.data_b_l1); + l1_data_B_sram_free(mod->arch.bss_b_l1); + l2_sram_free(mod->arch.text_l2); + l2_sram_free(mod->arch.data_l2); + l2_sram_free(mod->arch.bss_l2); } diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 861a1db74df8..8671d1db1f99 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -104,6 +104,7 @@ void __init bf53x_relocate_l1_mem(void) unsigned long l1_code_length; unsigned long l1_data_a_length; unsigned long l1_data_b_length; + unsigned long l2_length; l1_code_length = _etext_l1 - _stext_l1; if (l1_code_length > L1_CODE_LENGTH) @@ -129,6 +130,15 @@ void __init bf53x_relocate_l1_mem(void) /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + l1_data_a_length, l1_data_b_length); + +#ifdef L2_LENGTH + l2_length = _ebss_l2 - _stext_l2; + if (l2_length > L2_LENGTH) + panic("L2 SRAM Overflow\n"); + + /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ + dma_memcpy(_stext_l2, _l2_lma_start, l2_length); +#endif } /* add_memory_region to memmap */ diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 3ecc64cab3be..0896e38d6108 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -101,6 +101,11 @@ SECTIONS #if !L1_DATA_B_LENGTH *(.l1.data.B) #endif +#ifndef L2_LENGTH + . = ALIGN(32); + *(.data_l2.cacheline_aligned) + *(.l2.data) +#endif DATA_DATA *(.data.*) @@ -182,13 +187,12 @@ SECTIONS *(.l1.data) __edata_l1 = .; - . = ALIGN(4); - __sbss_l1 = .; - *(.l1.bss) - . = ALIGN(32); *(.data_l1.cacheline_aligned) + . = ALIGN(4); + __sbss_l1 = .; + *(.l1.bss) . = ALIGN(4); __ebss_l1 = .; } @@ -203,11 +207,37 @@ SECTIONS . = ALIGN(4); __sbss_b_l1 = .; *(.l1.bss.B) - . = ALIGN(4); __ebss_b_l1 = .; } +#ifdef L2_LENGTH + __l2_lma_start = .; + + .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) + { + . = ALIGN(4); + __stext_l2 = .; + *(.l1.text) + . = ALIGN(4); + __etext_l2 = .; + + . = ALIGN(4); + __sdata_l2 = .; + *(.l1.data) + __edata_l2 = .; + + . = ALIGN(32); + *(.data_l2.cacheline_aligned) + + . = ALIGN(4); + __sbss_l2 = .; + *(.l1.bss) + . = ALIGN(4); + __ebss_l2 = .; + } +#endif + /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. */ diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index b58cf196d7cc..5af3c31c9365 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -42,6 +42,7 @@ #include "blackfin_sram.h" static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; +static spinlock_t l2_sram_lock; /* the data structure for L1 scratchpad and DATA SRAM */ struct sram_piece { @@ -65,6 +66,10 @@ static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; #endif +#ifdef L2_LENGTH +static struct sram_piece free_l2_sram_head, used_l2_sram_head; +#endif + static struct kmem_cache *sram_piece_cache; /* L1 Scratchpad SRAM initialization function */ @@ -97,7 +102,7 @@ static void __init l1_data_sram_init(void) free_l1_data_A_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_A_sram_head.next) { - printk(KERN_INFO"Fail to initialize Data A SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n"); return; } @@ -110,7 +115,7 @@ static void __init l1_data_sram_init(void) used_l1_data_A_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n", L1_DATA_A_LENGTH >> 10, free_l1_data_A_sram_head.next->size >> 10); #endif @@ -118,7 +123,7 @@ static void __init l1_data_sram_init(void) free_l1_data_B_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_B_sram_head.next) { - printk(KERN_INFO"Fail to initialize Data B SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n"); return; } @@ -131,7 +136,7 @@ static void __init l1_data_sram_init(void) used_l1_data_B_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n", L1_DATA_B_LENGTH >> 10, free_l1_data_B_sram_head.next->size >> 10); #endif @@ -146,7 +151,7 @@ static void __init l1_inst_sram_init(void) free_l1_inst_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_inst_sram_head.next) { - printk(KERN_INFO"Fail to initialize Instruction SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n"); return; } @@ -159,7 +164,7 @@ static void __init l1_inst_sram_init(void) used_l1_inst_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n", L1_CODE_LENGTH >> 10, free_l1_inst_sram_head.next->size >> 10); #endif @@ -168,6 +173,33 @@ static void __init l1_inst_sram_init(void) spin_lock_init(&l1_inst_sram_lock); } +static void __init l2_sram_init(void) +{ +#ifdef L2_LENGTH + free_l2_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l2_sram_head.next) { + printk(KERN_INFO"Fail to initialize L2 SRAM.\n"); + return; + } + + free_l2_sram_head.next->paddr = (void *)L2_START + + (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); + free_l2_sram_head.next->size = L2_LENGTH - + (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); + free_l2_sram_head.next->pid = 0; + free_l2_sram_head.next->next = NULL; + + used_l2_sram_head.next = NULL; + + printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n", + L2_LENGTH >> 10, + free_l2_sram_head.next->size >> 10); +#endif + + /* mutex initialize */ + spin_lock_init(&l2_sram_lock); +} void __init bfin_sram_init(void) { sram_piece_cache = kmem_cache_create("sram_piece_cache", @@ -177,10 +209,11 @@ void __init bfin_sram_init(void) l1sram_init(); l1_data_sram_init(); l1_inst_sram_init(); + l2_sram_init(); } -/* L1 memory allocate function */ -static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, +/* SRAM allocate function */ +static void *_sram_alloc(size_t size, struct sram_piece *pfree_head, struct sram_piece *pused_head) { struct sram_piece *pslot, *plast, *pavail; @@ -236,7 +269,7 @@ static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, } /* Allocate the largest available block. */ -static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, +static void *_sram_alloc_max(struct sram_piece *pfree_head, struct sram_piece *pused_head, unsigned long *psize) { @@ -259,11 +292,11 @@ static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, *psize = pmax->size; - return _l1_sram_alloc(*psize, pfree_head, pused_head); + return _sram_alloc(*psize, pfree_head, pused_head); } -/* L1 memory free function */ -static int _l1_sram_free(const void *addr, +/* SRAM free function */ +static int _sram_free(const void *addr, struct sram_piece *pfree_head, struct sram_piece *pused_head) { @@ -333,6 +366,11 @@ int sram_free(const void *addr) else if (addr >= (void *)L1_DATA_B_START && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) return l1_data_B_sram_free(addr); +#endif +#ifdef L2_LENGTH + else if (addr >= (void *)L2_START + && addr < (void *)(L2_START + L2_LENGTH)) + return l2_sram_free(addr); #endif else return -1; @@ -348,7 +386,7 @@ void *l1_data_A_sram_alloc(size_t size) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - addr = _l1_sram_alloc(size, &free_l1_data_A_sram_head, + addr = _sram_alloc(size, &free_l1_data_A_sram_head, &used_l1_data_A_sram_head); #endif @@ -371,7 +409,7 @@ int l1_data_A_sram_free(const void *addr) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - ret = _l1_sram_free(addr, &free_l1_data_A_sram_head, + ret = _sram_free(addr, &free_l1_data_A_sram_head, &used_l1_data_A_sram_head); #else ret = -1; @@ -393,7 +431,7 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_data_B_sram_head, + addr = _sram_alloc(size, &free_l1_data_B_sram_head, &used_l1_data_B_sram_head); /* add mutex operation */ @@ -418,7 +456,7 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_data_B_sram_head, + ret = _sram_free(addr, &free_l1_data_B_sram_head, &used_l1_data_B_sram_head); /* add mutex operation */ @@ -472,7 +510,7 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_inst_sram_head, + addr = _sram_alloc(size, &free_l1_inst_sram_head, &used_l1_inst_sram_head); /* add mutex operation */ @@ -497,7 +535,7 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_inst_sram_head, + ret = _sram_free(addr, &free_l1_inst_sram_head, &used_l1_inst_sram_head); /* add mutex operation */ @@ -519,7 +557,7 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_ssram_head, + addr = _sram_alloc(size, &free_l1_ssram_head, &used_l1_ssram_head); /* add mutex operation */ @@ -537,7 +575,7 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc_max(&free_l1_ssram_head, + addr = _sram_alloc_max(&free_l1_ssram_head, &used_l1_ssram_head, psize); /* add mutex operation */ @@ -555,7 +593,7 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_ssram_head, + ret = _sram_free(addr, &free_l1_ssram_head, &used_l1_ssram_head); /* add mutex operation */ @@ -564,6 +602,64 @@ int l1sram_free(const void *addr) return ret; } +void *l2_sram_alloc(size_t size) +{ +#ifdef L2_LENGTH + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l2_sram_lock, flags); + + addr = _sram_alloc(size, &free_l2_sram_head, + &used_l2_sram_head); + + /* add mutex operation */ + spin_unlock_irqrestore(&l2_sram_lock, flags); + + pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n", + (long unsigned int)addr, size); + + return addr; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(l2_sram_alloc); + +void *l2_sram_zalloc(size_t size) +{ + void *addr = l2_sram_alloc(size); + + if (addr) + memset(addr, 0x00, size); + + return addr; +} +EXPORT_SYMBOL(l2_sram_zalloc); + +int l2_sram_free(const void *addr) +{ +#ifdef L2_LENGTH + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l2_sram_lock, flags); + + ret = _sram_free(addr, &free_l2_sram_head, + &used_l2_sram_head); + + /* add mutex operation */ + spin_unlock_irqrestore(&l2_sram_lock, flags); + + return ret; +#else + return -1; +#endif +} +EXPORT_SYMBOL(l2_sram_free); + int sram_free_with_lsl(const void *addr) { struct sram_list_struct *lsl, **tmp; @@ -602,6 +698,9 @@ void *sram_alloc_with_lsl(size_t size, unsigned long flags) if (addr == NULL && (flags & L1_DATA_B_SRAM)) addr = l1_data_B_sram_alloc(size); + if (addr == NULL && (flags & L2_SRAM)) + addr = l2_sram_alloc(size); + if (addr == NULL) { kfree(lsl); return NULL; @@ -621,7 +720,7 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); /* Need to keep line of output the same. Currently, that is 44 bytes * (including newline). */ -static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, +static int _sram_proc_read(char *buf, int *len, int count, const char *desc, struct sram_piece *pfree_head, struct sram_piece *pused_head) { @@ -630,13 +729,13 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, if (!pfree_head || !pused_head) return -1; - *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); + *len += sprintf(&buf[*len], "--- SRAM %-14s Size PID State \n", desc); /* search the relevant memory slot */ pslot = pused_head->next; while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", pslot->paddr, pslot->paddr + pslot->size, pslot->size, pslot->pid, "ALLOCATED"); @@ -646,7 +745,7 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, pslot = pfree_head->next; while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", pslot->paddr, pslot->paddr + pslot->size, pslot->size, pslot->pid, "FREE"); @@ -655,38 +754,43 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, return 0; } -static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, +static int sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len = 0; - if (_l1sram_proc_read(buf, &len, count, "Scratchpad", + if (_sram_proc_read(buf, &len, count, "Scratchpad", &free_l1_ssram_head, &used_l1_ssram_head)) goto not_done; #if L1_DATA_A_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Data A", + if (_sram_proc_read(buf, &len, count, "L1 Data A", &free_l1_data_A_sram_head, &used_l1_data_A_sram_head)) goto not_done; #endif #if L1_DATA_B_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Data B", + if (_sram_proc_read(buf, &len, count, "L1 Data B", &free_l1_data_B_sram_head, &used_l1_data_B_sram_head)) goto not_done; #endif #if L1_CODE_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Instruction", + if (_sram_proc_read(buf, &len, count, "L1 Instruction", &free_l1_inst_sram_head, &used_l1_inst_sram_head)) goto not_done; #endif +#ifdef L2_LENGTH + if (_sram_proc_read(buf, &len, count, "L2", + &free_l2_sram_head, &used_l2_sram_head)) + goto not_done; +#endif *eof = 1; not_done: return len; } -static int __init l1sram_proc_init(void) +static int __init sram_proc_init(void) { struct proc_dir_entry *ptr; ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL); @@ -695,8 +799,8 @@ static int __init l1sram_proc_init(void) return -1; } ptr->owner = THIS_MODULE; - ptr->read_proc = l1sram_proc_read; + ptr->read_proc = sram_proc_read; return 0; } -late_initcall(l1sram_proc_init); +late_initcall(sram_proc_init); #endif diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h index 76033831eb35..320aa5e167e9 100644 --- a/include/asm-blackfin/bfin-global.h +++ b/include/asm-blackfin/bfin-global.h @@ -92,16 +92,20 @@ extern void *l1_data_B_sram_alloc(size_t); extern void *l1_inst_sram_alloc(size_t); extern void *l1_data_sram_alloc(size_t); extern void *l1_data_sram_zalloc(size_t); +extern void *l2_sram_alloc(size_t); +extern void *l2_sram_zalloc(size_t); extern int l1_data_A_sram_free(const void*); extern int l1_data_B_sram_free(const void*); extern int l1_inst_sram_free(const void*); extern int l1_data_sram_free(const void*); +extern int l2_sram_free(const void *); extern int sram_free(const void*); #define L1_INST_SRAM 0x00000001 #define L1_DATA_A_SRAM 0x00000002 #define L1_DATA_B_SRAM 0x00000004 #define L1_DATA_SRAM 0x00000006 +#define L2_SRAM 0x00000008 extern void *sram_alloc_with_lsl(size_t, unsigned long); extern int sram_free_with_lsl(const void*); @@ -114,7 +118,9 @@ extern struct file_operations dpmc_fops; extern unsigned long _ramstart, _ramend, _rambase; extern unsigned long memory_start, memory_end, physical_mem_end; extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], - _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[]; + _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[], + _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], + _ebss_l2[], _l2_lma_start[]; #ifdef CONFIG_MTD_UCLINUX extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; diff --git a/include/asm-blackfin/elf.h b/include/asm-blackfin/elf.h index 30303fc8292c..67a03a8a353e 100644 --- a/include/asm-blackfin/elf.h +++ b/include/asm-blackfin/elf.h @@ -15,6 +15,8 @@ #define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */ #define EF_BFIN_CODE_IN_L1 0x00000010 /* --code-in-l1 */ #define EF_BFIN_DATA_IN_L1 0x00000020 /* --data-in-l1 */ +#define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */ +#define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */ typedef unsigned long elf_greg_t; diff --git a/include/asm-blackfin/module.h b/include/asm-blackfin/module.h index 3c7ce1644280..e3128df139d6 100644 --- a/include/asm-blackfin/module.h +++ b/include/asm-blackfin/module.h @@ -6,8 +6,6 @@ #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr -#define FLG_CODE_IN_L1 0x10 -#define FLG_DATA_IN_L1 0x20 struct mod_arch_specific { Elf_Shdr *text_l1; @@ -15,5 +13,8 @@ struct mod_arch_specific { Elf_Shdr *bss_a_l1; Elf_Shdr *data_b_l1; Elf_Shdr *bss_b_l1; + Elf_Shdr *text_l2; + Elf_Shdr *data_l2; + Elf_Shdr *bss_l2; }; #endif /* _ASM_BFIN_MODULE_H */ -- cgit v1.2.3-59-g8ed1b