3 * - Open, Close and ChDir
11 #define MMAP_PAGES_PER_BLOCK 16
12 #define PAGE_SIZE 0x1000 // Should be in mm_virt.h
15 typedef struct sVFS_MMapPageBlock tVFS_MMapPageBlock;
16 struct sVFS_MMapPageBlock
18 tVFS_MMapPageBlock *Next;
19 Uint64 BaseOffset; // Must be a multiple of MMAP_PAGES_PER_BLOCK*PAGE_SIZE
20 tPAddr PhysAddrs[MMAP_PAGES_PER_BLOCK];
24 void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset)
29 tVFS_MMapPageBlock *pb, *prev;
31 npages = ((Offset & (PAGE_SIZE-1)) + Length) / PAGE_SIZE;
32 pagenum = Offset / PAGE_SIZE;
34 mapping_dest = (tVAddr)DestHint;
37 // TODO: Locate space for the allocation
38 if( Flags & MAP_ANONYMOUS )
40 MM_Allocate(mapping_dest);
41 return (void*)mapping_dest;
45 h = VFS_GetHandle(FD);
46 if( !h || !h->Node ) return NULL;
48 // Search for existing mapping for each page
49 // - Sorted list of 16 page blocks
51 pb = h->Node->MMapInfo, prev = NULL;
52 pb && pb->BaseOffset + MMAP_PAGES_PER_BLOCK < pagenum;
53 prev = pb, pb = pb->Next
56 // - Allocate a block if needed
57 if( !pb || pb->BaseOffset > pagenum )
60 pb = malloc( sizeof(tVFS_MMapPageBlock) );
63 pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK;
64 memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
68 h->Node->MMapInfo = pb;
71 // - Map (and allocate) pages
74 if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 )
77 h->Node->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
80 // Allocate pages and read data
81 if( MM_Allocate(mapping_dest) == 0 ) {
85 h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
87 pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
88 // MM_SetPageInfo( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node, pagenum*PAGE_SIZE );
92 MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
95 mapping_dest += PAGE_SIZE;
97 // Roll on to next block if needed
98 if(pagenum - pb->BaseOffset == MMAP_PAGES_PER_BLOCK)
100 if( pb->Next && pb->Next->BaseOffset == pagenum )
104 tVFS_MMapPageBlock *oldpb = pb;
105 pb = malloc( sizeof(tVFS_MMapPageBlock) );
106 pb->Next = oldpb->Next;
107 pb->BaseOffset = pagenum;
108 memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
118 int VFS_MUnmap(void *Addr, size_t Length)