Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // <proto.h>
- #define A(sym) __netbsd_driver_proxy__##sym
- extern void A(mem_init)();
- extern void* A(mem_alloc)(int request_size);
- extern int A(mem_get_class)(int pha);
- extern void A(mem_free)(void* pha_);
- extern void* A(mem_realloc)(void* pha, int request_size);
- #define mem_init(...) A(mem_init)(__VA_ARGS__)
- #define mem_alloc(...) A(mem_alloc)(__VA_ARGS__)
- #define mem_get_class(...) A(mem_get_class)(__VA_ARGS__)
- #define mem_free(...) A(mem_free)(__VA_ARGS__)
- #define mem_realloc(...) A(mem_realloc)(__VA_ARGS__)
- // <mem.c>
- //========
- #undef DEBUG
- //========
- // debug switch
- //#define DEBUG
- // memory layout
- #define MEMORY_PAGE_SIZE 0x1000 // 4K
- #define MEMORY_PAGES 0x2000 // 32M
- #define MEMORY_SHIFT_LIMIT 6
- #define MEMORY_CLASS_START 12 // 4K
- #define MEMORY_CLASS_END (MEMORY_SHIFT_LIMIT + MEMORY_CLASS_START) // 256K
- #define MEMORY_MEMORY_START_P 0x1000 // 16M
- #define MEMORY_MEMORY_END_P (MEMORY_MEMORY_START_P + MEMORY_PAGES) // 48M
- // check layout
- #if (2 << MEMORY_SHIFT_LIMIT) != (MEMORY_PAGES >> MEMORY_SHIFT_LIMIT)
- #error wrong memory class layout
- #endif
- #if 1 << MEMORY_SHIFT_LIMIT != MEMORY_PAGE_SIZE
- #error wrong memory configuration
- #endif
- // macros
- #define ADDR_ERROR(msg) { \
- print_str(msg); \
- halt(); \
- return (void*) 0; }
- #define INT_ERROR(msg) { \
- print_str(msg); \
- halt(); \
- return 0; }
- #define VOID_ERROR(msg) { \
- print_str(msg); \
- halt(); \
- return; }
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
- #pragma pack(push)
- #pragma pack(1)
- struct packed1 {
- char allocate_12[1 << 12]; // 4K * 4K = 16M start 0 sub 0x2000
- char allocate_13[1 << 10]; // 1K * 8K = 8M start 16 M sub 0x1000
- char allocate_14[1 << 8]; // 256 * 16K = 4M start 24 M sub 0x0800
- char allocate_15[1 << 6]; // 64 * 32K = 2M start 28 M sub 0x0400
- char allocate_16[1 << 4]; // 16 * 64K = 1M start 30 M sub 0x0200
- char allocate_17[1 << 2]; // 4 * 128K = 512K start 31 M sub 0x0100
- char allocate_18[1 << 1]; // 2 * 256K = 512K start 31.5M sub 0x0080
- // total 32 M
- char allocate_end[1];
- };
- #pragma pack(pop)
- static struct packed1 p1;
- static char* allocate[] = {
- (char*) p1.allocate_12,
- (char*) p1.allocate_13,
- (char*) p1.allocate_14,
- (char*) p1.allocate_15,
- (char*) p1.allocate_16,
- (char*) p1.allocate_17,
- (char*) p1.allocate_18,
- (char*) p1.allocate_end
- };
- extern void A(mem_init)() {
- memset((void*) p1.allocate_12, 0, 1 << 12);
- memset((void*) p1.allocate_13, 0, 1 << 10);
- memset((void*) p1.allocate_14, 0, 1 << 8);
- memset((void*) p1.allocate_15, 0, 1 << 6);
- memset((void*) p1.allocate_16, 0, 1 << 4);
- memset((void*) p1.allocate_17, 0, 1 << 2);
- memset((void*) p1.allocate_18, 0, 1 << 1);
- }
- extern void* A(mem_alloc)(int request_size) {
- int class = MEMORY_CLASS_START, class2, class3, class4;
- int provide_size, page_count, slot_count, slot = 0, pha;
- for(; class <= MEMORY_CLASS_END; ++class) { // 12 .. 18
- provide_size = 1 << class;
- if(request_size <= provide_size) {
- class2 = class - MEMORY_CLASS_START; // 0 .. 6
- class3 = (MEMORY_SHIFT_LIMIT - class2) << 1; // 12 .. 0
- class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
- page_count = 1 << class2; // allocated pages per slot
- slot_count = 1 << class3; // available slots of class
- if(class == MEMORY_CLASS_END)
- slot_count <<= 1; // duplicate last slot_count
- pha = MEMORY_MEMORY_END_P;
- pha -= 2 << class4; // first page of class
- /*slot_count++; // test
- if(&allocate[class2][slot_count] > &allocate[class2 + 1][0]) {
- ADDR_ERROR("malloc: invalid slot_count calculated")
- }*/
- for(; slot < slot_count; ++slot) {
- if(!allocate[class2][slot]) {
- allocate[class2][slot] = 0xFF; // mark allocated
- pha += page_count * slot; // add slot offset
- pha *= MEMORY_PAGE_SIZE; // calculate physical address from page index
- #ifdef DEBUG
- printf("a1[%d,%d,%d,%d.%d,%d,%d,%x]", class, class2, class3, class4, page_count, slot_count, slot, pha);
- #endif
- return (void*) pha;
- }
- }
- ADDR_ERROR("mem_alloc: no available memory left")
- }
- }
- printf("try to alloc %d\n", request_size);
- ADDR_ERROR("mem_alloc: size too big")
- }
- extern int A(mem_get_class)(int pha) {
- int class = MEMORY_CLASS_START, class2 = 0, class4 = 0, next_class = MEMORY_CLASS_START + 1, next_class2, next_class4;
- int next_pha2;
- if(pha % MEMORY_PAGE_SIZE != 0) {
- INT_ERROR("mem_get_class: address not aligned to 4k page bounds")
- }
- pha /= MEMORY_PAGE_SIZE; // calculate page index from physical address
- if(pha < MEMORY_MEMORY_START_P
- || pha >= MEMORY_MEMORY_END_P) {
- INT_ERROR("mem_get_class: address not in range")
- }
- next_class2 = class - MEMORY_CLASS_START; // 0 .. 6
- next_class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
- for(; class <= MEMORY_CLASS_END; ++class, ++next_class) { // 12 .. 18
- class2 = next_class2;
- class4 = next_class4;
- if(class < MEMORY_CLASS_END) {
- next_class2 = next_class - MEMORY_CLASS_START; // 0 .. 6
- next_class4 = (MEMORY_SHIFT_LIMIT << 1) - next_class2; // 12 .. 6
- next_pha2 = MEMORY_MEMORY_END_P;
- next_pha2 -= 2 << next_class4; // first page of class
- }
- else {
- next_pha2 = MEMORY_MEMORY_END_P; // end of last class
- }
- #ifdef DEBUG
- //printf("gc1[%d,%d,%d/%d,%d,%d.%x<%x]", class, class2, class4, next_class, next_class2, next_class4, pha, next_pha2);
- #endif
- if(pha < next_pha2) {
- #ifdef DEBUG
- printf("gc2[%d,%d,%d/%d,%d,%d]", class, class2, class4, next_class, next_class2, next_class4);
- #endif
- return class;
- }
- }
- INT_ERROR("mem_get_class: NOT REACHED")
- }
- extern void A(mem_free)(void* pha_) {
- int pha = (int) pha_;
- int class, class2, class4;
- int page_count, slot;
- class = mem_get_class(pha);
- if(pha % MEMORY_PAGE_SIZE != 0) {
- VOID_ERROR("mem_free: address not aligned to 4k page bounds")
- }
- pha /= MEMORY_PAGE_SIZE; // calculate page index from physical address
- if(pha < MEMORY_MEMORY_START_P
- || pha >= MEMORY_MEMORY_END_P) {
- VOID_ERROR("mem_free: address not in range")
- }
- class2 = class - MEMORY_CLASS_START; // 0 .. 6
- class4 = (MEMORY_SHIFT_LIMIT << 1) - class2; // 12 .. 6
- pha += 2 << class4; // first page of class
- pha -= MEMORY_MEMORY_END_P;
- page_count = 1 << class2; // allocated pages per slot
- if(pha % page_count != 0) {
- VOID_ERROR("mem_free: address not aligned to page_count")
- }
- slot = pha / page_count; // extract slot
- #ifdef DEBUG
- printf("f1[%d,%d,%d.%d,%d]", class, class2, class4, page_count, slot);
- #endif
- allocate[class2][slot] = 0; // mark unallocated
- return;
- }
- extern void* A(mem_realloc)(void* pha, int request_size) {
- int class1, class2;
- class1 = mem_get_class((int) pha);
- void *pha2 = mem_alloc(request_size);
- class2 = mem_get_class((int) pha2);
- #ifdef DEBUG
- printf("r1[%d,%d,%d.%d,%d]", class1, class2, MIN(class1, class2), 1 << MIN(class1, class2));
- #endif
- memcpy(pha2, pha, 1 << MIN(class1, class2));
- mem_free(pha);
- return pha2;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement