| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "iomem.h"
- #include "printf.h"
- #include "atomic.h"
- #define IOMEM_BLOCK_SIZE 256
- typedef struct _iomem_malloc_t
- {
- void (*init)();
- uint32_t (*unused)();
- uint8_t *membase;
- uint32_t memsize;
- uint32_t memtblsize;
- uint16_t *memmap;
- uint8_t memrdy;
- _lock_t *lock;
- } iomem_malloc_t;
- static _lock_t iomem_lock;
- static void iomem_init();
- static uint32_t k_unused();
- extern char *_ioheap_line;
- extern char *_heap_line;
- extern char _heap_start[];
- extern char *_heap_cur;
- iomem_malloc_t malloc_cortol =
- {
- iomem_init,
- k_unused,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- &iomem_lock
- };
- static void iomem_set(void *s, uint8_t c, uint32_t num)
- {
- uint8_t *xs = s;
- while(num--)
- *xs++=c;
- }
- static void iomem_init()
- {
- malloc_cortol.membase = (uint8_t *)((uintptr_t)_heap_line-0x40000000);
- malloc_cortol.memsize = (uint32_t)_ioheap_line - (uint32_t)malloc_cortol.membase;
- malloc_cortol.memtblsize = malloc_cortol.memsize / IOMEM_BLOCK_SIZE;
- malloc_cortol.memmap = (uint16_t *)malloc(malloc_cortol.memtblsize * 2);
- mb();
- malloc_cortol.membase = (uint8_t *)((uintptr_t)_heap_line-0x40000000);
- malloc_cortol.memsize = (uint32_t)_ioheap_line - (uint32_t)malloc_cortol.membase;
- malloc_cortol.memtblsize = malloc_cortol.memsize / IOMEM_BLOCK_SIZE;
- iomem_set(malloc_cortol.memmap, 0, malloc_cortol.memtblsize * 2);
- iomem_set(malloc_cortol.membase, 0, malloc_cortol.memsize);
- malloc_cortol.memrdy = 1;
- }
- static uint32_t k_unused()
- {
- uint32_t unused=0;
- unused = (uintptr_t)_ioheap_line + 0x40000000 - (uintptr_t)_heap_line;
- return unused;
- }
- static uint32_t k_malloc(uint32_t size)
- {
- signed long offset = 0;
- uint32_t xmemb;
- uint32_t kmemb = 0;
- if(!malloc_cortol.memrdy)
- malloc_cortol.init();
- if(size==0)
- return 0XFFFFFFFF;
- xmemb=size / IOMEM_BLOCK_SIZE;
- if(size % IOMEM_BLOCK_SIZE)
- xmemb++;
- for(offset=malloc_cortol.memtblsize-1; offset>=0; offset--)
- {
- if(!malloc_cortol.memmap[offset])
- {
- kmemb++;
- }
- else
- {
- offset = offset - malloc_cortol.memmap[offset] + 1;
- kmemb=0;
- }
- if(kmemb==xmemb)
- {
- malloc_cortol.memmap[offset] = xmemb;
- malloc_cortol.memmap[offset+xmemb-1] = xmemb;
- return (offset * IOMEM_BLOCK_SIZE);
- }
- }
- return 0XFFFFFFFF;
- }
- static uint8_t k_free(uint32_t offset)
- {
- if(!malloc_cortol.memrdy)
- {
- malloc_cortol.init();
- return 1;
- }
- if(offset < malloc_cortol.memsize)
- {
- int index=offset / IOMEM_BLOCK_SIZE;
- int nmemb=malloc_cortol.memmap[index];
- malloc_cortol.memmap[index] = 0;
- malloc_cortol.memmap[index+nmemb-1] = 0;
- if((uintptr_t)_ioheap_line == (uintptr_t)malloc_cortol.membase + offset)
- {
- _ioheap_line = (char *)((uintptr_t)_ioheap_line + nmemb * IOMEM_BLOCK_SIZE);
- }
- return 0;
- }
- else
- return 2;
- }
- void iomem_free(void *paddr)
- {
- uint32_t offset;
- if(paddr == NULL)
- return;
- _lock_acquire_recursive(malloc_cortol.lock);
- offset=(uintptr_t)paddr - (uintptr_t)malloc_cortol.membase;
- k_free(offset);
- _lock_release_recursive(malloc_cortol.lock);
- }
- void *iomem_malloc(uint32_t size)
- {
- _lock_acquire_recursive(malloc_cortol.lock);
- uint32_t offset;
- offset=k_malloc(size);
- if(offset == 0XFFFFFFFF)
- {
- printk("IOMEM malloc OUT of MEMORY!\r\n");
- _lock_release_recursive(malloc_cortol.lock);
- return NULL;
- }
- else
- {
- if((uintptr_t)_ioheap_line > (uintptr_t)malloc_cortol.membase + offset)
- {
- _ioheap_line = (char *)((uintptr_t)malloc_cortol.membase + offset);
- if((uintptr_t)_ioheap_line < (uintptr_t)_heap_line-0x40000000)
- {
- printk("Error: OUT of MEMORY!\r\n");
- printk("_heap_line = %p\r\n", _heap_line);
- printk("_ioheap_line = %p\r\n", _ioheap_line);
- while(1)
- ;
- }
- };
- _lock_release_recursive(malloc_cortol.lock);
- return (void*)((uintptr_t)malloc_cortol.membase + offset);
- }
- }
- uint32_t iomem_unused()
- {
- return malloc_cortol.unused();
- }
|