SHARE
TWEET

mem.c

Dimension Jul 25th, 2012 88 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top