Advertisement
Dimension

mem.c

Jul 25th, 2012
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.11 KB | None | 0 0
  1. // <proto.h>
  2. #define A(sym) __netbsd_driver_proxy__##sym
  3.  
  4. extern void A(mem_init)();
  5. extern void* A(mem_alloc)(int request_size);
  6. extern int A(mem_get_class)(int pha);
  7. extern void A(mem_free)(void* pha_);
  8. extern void* A(mem_realloc)(void* pha, int request_size);
  9.  
  10. #define mem_init(...) A(mem_init)(__VA_ARGS__)
  11. #define mem_alloc(...) A(mem_alloc)(__VA_ARGS__)
  12. #define mem_get_class(...) A(mem_get_class)(__VA_ARGS__)
  13. #define mem_free(...) A(mem_free)(__VA_ARGS__)
  14. #define mem_realloc(...) A(mem_realloc)(__VA_ARGS__)
  15.  
  16. // <mem.c>
  17. //========
  18. #undef DEBUG
  19. //========
  20.  
  21. // debug switch
  22. //#define DEBUG
  23.  
  24.  
  25. // memory layout
  26. #define MEMORY_PAGE_SIZE 0x1000 // 4K
  27. #define MEMORY_PAGES 0x2000 // 32M
  28.  
  29. #define MEMORY_SHIFT_LIMIT 6
  30. #define MEMORY_CLASS_START 12 // 4K
  31. #define MEMORY_CLASS_END (MEMORY_SHIFT_LIMIT + MEMORY_CLASS_START) // 256K
  32.  
  33. #define MEMORY_MEMORY_START_P 0x1000 // 16M
  34. #define MEMORY_MEMORY_END_P (MEMORY_MEMORY_START_P + MEMORY_PAGES) // 48M
  35.  
  36.  
  37. // check layout
  38. #if (2 << MEMORY_SHIFT_LIMIT) != (MEMORY_PAGES >> MEMORY_SHIFT_LIMIT)
  39.     #error wrong memory class layout
  40. #endif
  41. #if 1 << MEMORY_SHIFT_LIMIT != MEMORY_PAGE_SIZE
  42.     #error wrong memory configuration
  43. #endif
  44.  
  45. // macros
  46. #define ADDR_ERROR(msg) { \
  47.     print_str(msg); \
  48.     halt(); \
  49.     return (void*) 0; }
  50.  
  51. #define INT_ERROR(msg) { \
  52.     print_str(msg); \
  53.     halt(); \
  54.     return 0; }
  55.  
  56. #define VOID_ERROR(msg) { \
  57.     print_str(msg); \
  58.     halt(); \
  59.     return; }
  60.  
  61. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  62.  
  63.  
  64. #pragma pack(push)
  65. #pragma pack(1)
  66. struct packed1 {
  67. char allocate_12[1 << 12]; //  4K *   4K =  16M  start  0     sub 0x2000
  68. char allocate_13[1 << 10]; //  1K *   8K =   8M  start 16  M  sub 0x1000
  69. char allocate_14[1 <<  8]; // 256 *  16K =   4M  start 24  M  sub 0x0800
  70. char allocate_15[1 <<  6]; //  64 *  32K =   2M  start 28  M  sub 0x0400
  71. char allocate_16[1 <<  4]; //  16 *  64K =   1M  start 30  M  sub 0x0200
  72. char allocate_17[1 <<  2]; //   4 * 128K = 512K  start 31  M  sub 0x0100
  73. char allocate_18[1 <<  1]; //   2 * 256K = 512K  start 31.5M  sub 0x0080
  74.                            //                    total 32  M
  75. char allocate_end[1];
  76. };
  77. #pragma pack(pop)
  78.  
  79. static struct packed1 p1;
  80.  
  81. static char* allocate[] = {
  82.     (char*) p1.allocate_12,
  83.     (char*) p1.allocate_13,
  84.     (char*) p1.allocate_14,
  85.     (char*) p1.allocate_15,
  86.     (char*) p1.allocate_16,
  87.     (char*) p1.allocate_17,
  88.     (char*) p1.allocate_18,
  89.     (char*) p1.allocate_end
  90. };
  91.  
  92.  
  93. extern void A(mem_init)() {
  94.     memset((void*) p1.allocate_12, 0, 1 << 12);
  95.     memset((void*) p1.allocate_13, 0, 1 << 10);
  96.     memset((void*) p1.allocate_14, 0, 1 <<  8);
  97.     memset((void*) p1.allocate_15, 0, 1 <<  6);
  98.     memset((void*) p1.allocate_16, 0, 1 <<  4);
  99.     memset((void*) p1.allocate_17, 0, 1 <<  2);
  100.     memset((void*) p1.allocate_18, 0, 1 <<  1);
  101. }
  102.  
  103. extern void* A(mem_alloc)(int request_size) {
  104.     int class = MEMORY_CLASS_START, class2, class3, class4;
  105.     int provide_size, page_count, slot_count, slot = 0, pha;
  106.    
  107.     for(; class <= MEMORY_CLASS_END; ++class) { // 12 .. 18
  108.         provide_size = 1 << class;
  109.         if(request_size <= provide_size) {
  110.        
  111.             class2 = class - MEMORY_CLASS_START;         //  0 .. 6
  112.             class3 = (MEMORY_SHIFT_LIMIT - class2) << 1; // 12 .. 0
  113.             class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
  114.            
  115.             page_count = 1 << class2; // allocated pages per slot
  116.             slot_count = 1 << class3; // available slots of class
  117.             if(class == MEMORY_CLASS_END)
  118.                 slot_count <<= 1; // duplicate last slot_count
  119.            
  120.             pha = MEMORY_MEMORY_END_P;
  121.             pha -= 2 << class4; // first page of class
  122.            
  123.             /*slot_count++; // test
  124.             if(&allocate[class2][slot_count] > &allocate[class2 + 1][0]) {
  125.                 ADDR_ERROR("malloc: invalid slot_count calculated")
  126.             }*/
  127.            
  128.             for(; slot < slot_count; ++slot) {
  129.                 if(!allocate[class2][slot]) {
  130.                     allocate[class2][slot] = 0xFF; // mark allocated
  131.                    
  132.                     pha += page_count * slot; // add slot offset
  133.                     pha *= MEMORY_PAGE_SIZE; // calculate physical address from page index
  134.                    
  135. #ifdef DEBUG
  136.                     printf("a1[%d,%d,%d,%d.%d,%d,%d,%x]", class, class2, class3, class4, page_count, slot_count, slot, pha);
  137. #endif
  138.            
  139.                     return (void*) pha;
  140.                 }
  141.             }
  142.            
  143.             ADDR_ERROR("mem_alloc: no available memory left")
  144.         }
  145.     }
  146.    
  147.     printf("try to alloc %d\n", request_size);
  148.     ADDR_ERROR("mem_alloc: size too big")
  149. }
  150.  
  151. extern int A(mem_get_class)(int pha) {
  152.     int class = MEMORY_CLASS_START, class2 = 0, class4 = 0, next_class = MEMORY_CLASS_START + 1, next_class2, next_class4;
  153.     int next_pha2;
  154.    
  155.     if(pha % MEMORY_PAGE_SIZE != 0) {
  156.         INT_ERROR("mem_get_class: address not aligned to 4k page bounds")
  157.     }
  158.    
  159.     pha /= MEMORY_PAGE_SIZE; // calculate page index from physical address
  160.    
  161.     if(pha < MEMORY_MEMORY_START_P
  162.     || pha >= MEMORY_MEMORY_END_P) {
  163.         INT_ERROR("mem_get_class: address not in range")
  164.     }
  165.    
  166.     next_class2 = class - MEMORY_CLASS_START;         //  0 .. 6
  167.     next_class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
  168.    
  169.     for(; class <= MEMORY_CLASS_END; ++class, ++next_class) { // 12 .. 18
  170.        
  171.         class2 = next_class2;
  172.         class4 = next_class4;
  173.        
  174.         if(class < MEMORY_CLASS_END) {
  175.             next_class2 = next_class - MEMORY_CLASS_START;         //  0 .. 6
  176.             next_class4 = (MEMORY_SHIFT_LIMIT << 1) - next_class2; // 12 .. 6
  177.        
  178.             next_pha2 = MEMORY_MEMORY_END_P;
  179.             next_pha2 -= 2 << next_class4; // first page of class
  180.         }
  181.         else {
  182.             next_pha2 = MEMORY_MEMORY_END_P; // end of last class
  183.         }
  184.  
  185. #ifdef DEBUG
  186.         //printf("gc1[%d,%d,%d/%d,%d,%d.%x<%x]", class, class2, class4, next_class, next_class2, next_class4, pha, next_pha2);
  187. #endif
  188.            
  189.         if(pha < next_pha2) {
  190.            
  191. #ifdef DEBUG
  192.             printf("gc2[%d,%d,%d/%d,%d,%d]", class, class2, class4, next_class, next_class2, next_class4);
  193. #endif
  194.             return class;
  195.         }
  196.     }
  197.    
  198.     INT_ERROR("mem_get_class: NOT REACHED")
  199. }
  200.  
  201. extern void A(mem_free)(void* pha_) {
  202.     int pha = (int) pha_;
  203.     int class, class2, class4;
  204.     int page_count, slot;
  205.    
  206.     class = mem_get_class(pha);
  207.    
  208.     if(pha % MEMORY_PAGE_SIZE != 0) {
  209.         VOID_ERROR("mem_free: address not aligned to 4k page bounds")
  210.     }
  211.    
  212.     pha /= MEMORY_PAGE_SIZE; // calculate page index from physical address
  213.    
  214.     if(pha < MEMORY_MEMORY_START_P
  215.     || pha >= MEMORY_MEMORY_END_P) {
  216.         VOID_ERROR("mem_free: address not in range")
  217.     }
  218.    
  219.     class2 = class - MEMORY_CLASS_START;         //  0 .. 6
  220.     class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
  221.            
  222.     pha += 2 << class4; // first page of class
  223.     pha -= MEMORY_MEMORY_END_P;
  224.    
  225.     page_count = 1 << class2; // allocated pages per slot
  226.  
  227.     if(pha % page_count != 0) {
  228.         VOID_ERROR("mem_free: address not aligned to page_count")
  229.     }
  230.    
  231.     slot = pha / page_count; // extract slot
  232.    
  233. #ifdef DEBUG
  234.     printf("f1[%d,%d,%d.%d,%d]", class, class2, class4, page_count, slot);
  235. #endif
  236.        
  237.     allocate[class2][slot] = 0; // mark unallocated
  238.     return;
  239. }
  240.  
  241. extern void* A(mem_realloc)(void* pha, int request_size) {
  242.     int class1, class2;
  243.    
  244.     class1 = mem_get_class((int) pha);
  245.    
  246.     void *pha2 = mem_alloc(request_size);
  247.     class2 = mem_get_class((int) pha2);
  248.    
  249. #ifdef DEBUG
  250.     printf("r1[%d,%d,%d.%d,%d]", class1, class2, MIN(class1, class2), 1 << MIN(class1, class2));
  251. #endif
  252.  
  253.     memcpy(pha2, pha, 1 << MIN(class1, class2));
  254.     mem_free(pha);
  255.     return pha2;
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement