Lots of work on the AcessNative kernel
[tpg/acess2.git] / AcessNative / ld-acess_src / memory.c
1 /*
2  */
3 #include "common.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6 #if __WIN32__
7 # include <windows.h>
8 #else
9 # include <sys/mman.h>
10 # include <errno.h>
11 #endif
12
13 // === PROTOTYPES ===
14  int    AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
15 uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
16
17 // === CODE ===
18 int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
19 {
20         uintptr_t       base = (VirtAddr >> 12) << 12;
21         size_t  size = (VirtAddr & 0xFFF) + ByteCount;
22         void    *tmp;
23         #if __WIN32__
24         tmp = VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
25         if( tmp == NULL ) {
26                 printf("ERROR: Unable to allocate memory (%i)\n", GetLastError());
27                 return -1;
28         }
29         #else
30         tmp = mmap((void*)base, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
31         if( tmp == MAP_FAILED ) {
32                 return -1;
33         }
34         #endif
35         return 0;
36 }
37
38 uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
39 {
40         #if __WIN32__
41         # error "Windows FindFreeRange() unimplemented"
42         #else
43         uintptr_t       base, ofs, size;
44         uintptr_t       end = -1;
45         static const int        PAGE_SIZE = 0x1000;
46         
47         size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE;
48         size *= PAGE_SIZE;
49
50         end <<= (sizeof(intptr_t)*8-MaxBits);
51         end >>= (sizeof(intptr_t)*8-MaxBits);
52         printf("end = %p\n", (void*)end);
53         
54 //      for( base = 0; base < end - size; base -= PAGE_SIZE )
55         for( base = end - size + 1; base > 0; base -= PAGE_SIZE )
56         {
57                 for( ofs = 0; ofs < size; ofs += PAGE_SIZE ) {
58                         if( msync( (void*)(base+ofs), 1, 0) == 0 )
59                                 break;
60                         if( errno != ENOMEM )
61                                 perror("FindFreeRange, msync");
62                 }
63                 if( ofs >= size ) {
64                         return base;
65                 }
66         }
67         return 0;
68         #endif
69 }

UCC git Repository :: git.ucc.asn.au