root/core/memmgmt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. chdk_heap_init
  2. chdk_heap_create
  3. chdk_malloc
  4. chdk_free
  5. chdk_meminfo
  6. chdk_testing
  7. exmem_testing
  8. exmem_malloc_init
  9. GetExMemInfo
  10. aram_testing
  11. aram_malloc_init
  12. GetARamInfo
  13. canon_malloc_init
  14. combine_meminfo
  15. GetCombinedMemInfo
  16. malloc
  17. free
  18. get_exmem_type_name
  19. get_exmem_type_status

   1 #include "platform.h"
   2 #include "core.h"
   3 #include "conf.h"
   4 #include "gui_draw.h"
   5 #include "exmem.h"
   6 #include "semaphore.h"
   7 #include "ctype.h"
   8 
   9 //----------------------------------------------------------------------------
  10 // Memory wrappers
  11 
  12 extern void *suba_init(void *heap, unsigned size, unsigned mincell, char *name);
  13 extern void *suba_alloc(void *heap, unsigned size, unsigned zero);
  14 extern int suba_free(void *heap, void *p);
  15 
  16 //----------------------------------------------------------------------------
  17 // Manage block of memory controlled by suba
  18 typedef struct
  19 {
  20     void    *heap;
  21     void    *start;
  22     void    *end;
  23     int     size;
  24 } chdk_heap;
  25 
  26 static void chdk_heap_init(chdk_heap *h)
  27 {
  28     h->heap = 0;
  29     h->start = 0;
  30     h->end = 0;
  31     h->size = 0;
  32 }
  33 
  34 #if defined(OPT_EXMEM_MALLOC) || defined(OPT_ARAM_MALLOC)
  35 static void chdk_heap_create(chdk_heap *h, void *mem, int size, int chdk_in_heap, int heap_testing, char *name)
  36 {
  37     if (h)
  38     {
  39         if (chdk_in_heap)
  40         {
  41                     // If loading CHDK into heap then move heap start past the end of CHDK
  42                     // and reduce available space by CHDK size (MEMISOSIZE)
  43                     // round MEMISOSIZE up to next 4 byte boundary if needed (just in case)
  44                     h->start = mem + ((camera_info.memisosize+3)&0xFFFFFFFC);
  45                     h->size = size - ((camera_info.memisosize+3)&0xFFFFFFFC);
  46         }
  47         else
  48         {
  49                     // Set start & size based on requested values
  50                     h->start = mem;
  51                     h->size = size;
  52         }
  53 
  54                 h->end = h->start + h->size;
  55 
  56         if (heap_testing)
  57         {
  58                     // For testing exmem allocated memory for corruption from normal camera operations
  59                     // set the above #define. This will allocate the memory; but won't use it (exmem_heap is set to 0)
  60                     // Instead all the memory is filled with the guard value below.
  61                     // In gui_draw_debug_vals_osd (gui.c) the memory is tested for the guard value and if any
  62                     // corruption has occurred then info about the memory locations that were altered is displayed
  63             // Note: do not use heap_testing and chdk_in_heap at the same time
  64                     unsigned long *p;
  65                     for (p=(unsigned long*)h->start; p<(unsigned long*)h->end; p++) *p = 0xDEADBEEF;
  66         }
  67         else
  68         {
  69                 // Normal operation, use the suba allocation system to manage the memory block
  70                 h->heap = suba_init(h->start,h->size,8,name);
  71         }
  72     }
  73 }
  74 #endif
  75 
  76 static void* chdk_malloc(chdk_heap *h, unsigned size)
  77 {
  78     if (h && h->heap)
  79             return suba_alloc(h->heap,size,0);
  80     return 0;
  81 }
  82 
  83 static int chdk_free(chdk_heap *h, void *p)
  84 {
  85     if (h && h->heap && (p >= h->start) && (p < h->end))
  86     {
  87         suba_free(h->heap,p);
  88         return 1;
  89     }
  90     return 0;
  91 }
  92 
  93 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
  94 static int chdk_meminfo(chdk_heap *h, cam_meminfo *camera_meminfo)
  95 {
  96     if (h && h->heap)
  97     {
  98             extern void suba_getmeminfo(void*, int*, int*, int*, int*, int*, int*);
  99 
 100         camera_meminfo->start_address        = (int)h->start;
 101         camera_meminfo->end_address          = (int)h->end;
 102         camera_meminfo->total_size           = h->size;
 103         suba_getmeminfo(h->heap,
 104                         &camera_meminfo->allocated_size, &camera_meminfo->allocated_peak, &camera_meminfo->allocated_count,
 105                         &camera_meminfo->free_size, &camera_meminfo->free_block_max_size, &camera_meminfo->free_block_count);
 106 
 107         return 1;   // return success
 108     }
 109     else
 110     {
 111         memset(camera_meminfo, 0, sizeof(cam_meminfo));
 112         return 0;
 113     }
 114 }
 115 
 116 #if defined(OPT_EXMEM_TESTING) || defined(OPT_ARAM_TESTING)
 117 static void chdk_testing(chdk_heap *h)
 118 {
 119     // If defined the heap memory is allocated; but not used for CHDK.
 120     // It is filled with a guard value which is checked here
 121     // Any corruption is reported, otherwise 'OK' is displayed on screen (along with the heap memory start address).
 122 
 123     // check heap allocated memory for corruption
 124     unsigned long* p = (unsigned long*)h->start;
 125     unsigned long *f = 0, *l = 0;
 126     long cnt = 0;
 127     while (p < (unsigned long*)h->end)
 128     {
 129         if (p[0] != 0xDEADBEEF)
 130         {
 131             l = p;
 132             if (f == 0) f = p;
 133             cnt++;
 134         }
 135         p++;
 136     }
 137     char osd_buf[40];
 138     if (cnt != 0)
 139     {
 140         sprintf(osd_buf, "s:%8x e:%8x", h->start, h->end);
 141         draw_string(2*FONT_WIDTH, 12*FONT_HEIGHT, osd_buf, user_color(conf.osd_color));
 142         sprintf(osd_buf, "f:%8x l:%8x c:%d", f, l, cnt);
 143     }
 144     else
 145     {
 146         sprintf(osd_buf, "OK 0x%x", h->start);
 147     }
 148     draw_string(2*FONT_WIDTH, 13*FONT_HEIGHT, osd_buf, user_color(conf.osd_color));
 149     // end of check     
 150 }
 151 #endif
 152 
 153 //----------------------------------------------------------------------------
 154 #ifdef OPT_EXMEM_MALLOC
 155 // I set this up to 16 mb and it still booted...
 156 #ifndef EXMEM_HEAP_SKIP
 157 #define EXMEM_HEAP_SKIP 0
 158 #endif
 159 #ifndef EXMEM_BUFFER_SIZE
 160 #define EXMEM_BUFFER_SIZE (1024*1024*2) // default size if not specified by camera
 161 #endif
 162 #define EXMEM_HEAP_SIZE (EXMEM_BUFFER_SIZE+EXMEM_HEAP_SKIP)     // desired space + amount to skip for the movie buffers (if needed)
 163 #endif
 164 
 165 static chdk_heap exmem_heap;
 166 
 167 #if defined(OPT_EXMEM_TESTING)
 168 void exmem_testing()
 169 {
 170     chdk_testing(&exmem_heap);
 171 }
 172 #endif
 173 
 174 void exmem_malloc_init()
 175 {
 176     chdk_heap_init(&exmem_heap);
 177 #ifdef OPT_EXMEM_MALLOC
 178 #ifndef OPT_CHDK_IN_EXMEM
 179 #define OPT_CHDK_IN_EXMEM 0
 180 #endif
 181 #ifndef OPT_EXMEM_TESTING
 182 #define OPT_EXMEM_TESTING 0
 183 #endif
 184         // pool zero is EXMEM_RAMDISK on d10
 185         extern void *exmem_alloc_cached(unsigned int pool_id,unsigned int size,int unk,int unk2);
 186         void *mem = exmem_alloc_cached(0,EXMEM_HEAP_SIZE,0,0);
 187         if (mem)
 188     {
 189         chdk_heap_create(&exmem_heap, mem, EXMEM_BUFFER_SIZE, OPT_CHDK_IN_EXMEM, OPT_EXMEM_TESTING, "exmem_suba");
 190         }
 191 #endif
 192 }
 193 
 194 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
 195 int GetExMemInfo(cam_meminfo *camera_meminfo)
 196 {
 197     return chdk_meminfo(&exmem_heap, camera_meminfo);
 198 }
 199 
 200 //----------------------------------------------------------------------------
 201 
 202 static chdk_heap aram_heap;
 203 
 204 #if defined(OPT_ARAM_TESTING)
 205 void aram_testing()
 206 {
 207     chdk_testing(&aram_heap);
 208 }
 209 #endif
 210 
 211 void aram_malloc_init()
 212 {
 213     chdk_heap_init(&aram_heap);
 214 #ifdef OPT_ARAM_MALLOC
 215 #ifndef OPT_CHDK_IN_ARAM
 216 #define OPT_CHDK_IN_ARAM 0
 217 #endif
 218 #ifndef OPT_ARAM_TESTING
 219 #define OPT_ARAM_TESTING 0
 220 #endif
 221     chdk_heap_create(&aram_heap, (void*)ARAM_HEAP_START, ARAM_HEAP_SIZE, OPT_CHDK_IN_ARAM, OPT_ARAM_TESTING, "aram_suba");
 222 #endif
 223 }
 224 
 225 // Use suba functions to fill meminfo structure to match firmware GetMemInfo function
 226 int GetARamInfo(cam_meminfo *camera_meminfo)
 227 {
 228     return chdk_meminfo(&aram_heap, camera_meminfo);
 229 }
 230 
 231 // --------------------------------------------------------------------------
 232 // semaphore for canon heap on vxworks
 233 #if !defined(CAM_DRYOS)
 234 int canon_heap_sem;
 235 
 236 void canon_malloc_init(void) {
 237     canon_heap_sem=CreateBinarySemaphore("canonheap", 1);
 238 }
 239 #endif
 240 
 241 //----------------------------------------------------------------------------
 242 static void combine_meminfo(cam_meminfo *combined,cam_meminfo *m)
 243 {
 244     combined->total_size += m->total_size;
 245     if(m->free_block_max_size > combined->free_block_max_size)
 246     {
 247         combined->free_block_max_size = m->free_block_max_size; 
 248     }
 249     combined->free_size += m->free_size;
 250     combined->free_block_count += m->free_block_count;
 251     combined->allocated_size += m->allocated_size;
 252     combined->allocated_peak += m->allocated_peak;
 253     combined->allocated_count += m->allocated_count;
 254 }
 255 
 256 // Build a combined meminfo from available heaps
 257 // free block max size is the single largest free block
 258 // other fields are total, or zero where it doesn't make sense to combine
 259 void GetCombinedMemInfo(cam_meminfo *camera_meminfo)
 260 {
 261     // get system meminfo, should always be available
 262     GetMemInfo(camera_meminfo);
 263 // some fields are set to -1 for vxworks cams
 264 #if !defined(CAM_DRYOS)
 265     camera_meminfo->allocated_peak = 0;
 266     camera_meminfo->total_size = 0;
 267 #ifdef CAM_NO_MEMPARTINFO
 268     // a more useful base value than 0
 269     camera_meminfo->free_size = camera_meminfo->free_block_max_size;
 270     camera_meminfo->free_block_count = 0;
 271     camera_meminfo->allocated_size = 0;
 272     camera_meminfo->allocated_count = 0;
 273 #endif
 274 #endif
 275 
 276     // these don't make sense to combine
 277     camera_meminfo->start_address = camera_meminfo->end_address = 0;
 278 
 279     cam_meminfo m;
 280     if(GetARamInfo(&m)) {
 281         combine_meminfo(camera_meminfo,&m);
 282     }
 283     if(GetExMemInfo(&m)) {
 284         combine_meminfo(camera_meminfo,&m);
 285     }
 286 }
 287 
 288 void *malloc(long size)
 289 {
 290     extern void *canon_malloc(long size);
 291 
 292     void *p = chdk_malloc(&aram_heap,size);
 293 
 294     if (p == 0)
 295         p = chdk_malloc(&exmem_heap,size);
 296 
 297     if (p == 0)
 298         p = canon_malloc(size);
 299 
 300     return p;
 301 }
 302 
 303 void free(void *p)
 304 {
 305     extern void canon_free(void *p);
 306 
 307     if (!chdk_free(&aram_heap,p))
 308             if (!chdk_free(&exmem_heap,p))
 309             canon_free(p);
 310 }
 311 
 312 // --------------------------------------------------------------------------
 313 // exmem related functions
 314 
 315 // returns name of exmem type
 316 // NULL is returned for invalid types
 317 char *get_exmem_type_name(unsigned int type)
 318 {
 319     extern char* exmem_types_table[];
 320     
 321     if (type<exmem_type_count) {
 322         return exmem_types_table[type];
 323     }
 324     return 0;
 325 }
 326 
 327 // allocation status for type is returned in struct pointed to by allocinf
 328 // returns 1 for success, 0 otherwise
 329 int get_exmem_type_status(unsigned int type, exmem_alloc_info *allocinf)
 330 {
 331     extern exmem_alloc_info exmem_alloc_table[];
 332     if (type<exmem_type_count && allocinf) {
 333         allocinf->addr = exmem_alloc_table[type].addr;
 334         allocinf->len = exmem_alloc_table[type].len;
 335         return 1;
 336     }
 337     return 0;
 338 }

/* [<][>][^][v][top][bottom][index][help] */