3 * - Open, Close and ChDir
11 #define MMAP_PAGES_PER_BLOCK 16
14 typedef struct sVFS_MMapPageBlock tVFS_MMapPageBlock;
15 struct sVFS_MMapPageBlock
17 tVFS_MMapPageBlock *Next;
18 Uint64 BaseOffset; // Must be a multiple of MMAP_PAGES_PER_BLOCK*PAGE_SIZE
19 tPAddr PhysAddrs[MMAP_PAGES_PER_BLOCK];
23 void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset)
28 tVFS_MMapPageBlock *pb, *prev;
30 ENTER("pDestHint iLength xProtection xFlags xFD XOffset", DestHint, Length, Protection, Flags, FD, Offset);
32 npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
33 pagenum = Offset / PAGE_SIZE;
35 mapping_dest = (tVAddr)DestHint;
37 // TODO: Locate space for the allocation
39 // Handle anonymous mappings
40 if( Flags & MMAP_MAP_ANONYMOUS )
43 for( i = 0; i < npages; i ++ ) {
44 tPAddr rv = MM_Allocate(mapping_dest + i * PAGE_SIZE);
49 LEAVE_RET('p', (void*)mapping_dest);
52 h = VFS_GetHandle(FD);
53 if( !h || !h->Node ) LEAVE_RET('n', NULL);
57 // Search for existing mapping for each page
58 // - Sorted list of 16 page blocks
60 pb = h->Node->MMapInfo, prev = NULL;
61 pb && pb->BaseOffset + MMAP_PAGES_PER_BLOCK < pagenum;
62 prev = pb, pb = pb->Next
65 // - Allocate a block if needed
66 if( !pb || pb->BaseOffset > pagenum )
69 pb = malloc( sizeof(tVFS_MMapPageBlock) );
70 if(!pb) LEAVE_RET('n', NULL);
72 pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK;
73 memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
77 h->Node->MMapInfo = pb;
80 // - Map (and allocate) pages
83 if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 )
86 h->Node->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
89 // Allocate pages and read data
90 if( MM_Allocate(mapping_dest) == 0 ) {
94 h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
96 pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
97 // MM_SetPageInfo( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node, pagenum*PAGE_SIZE );
101 MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
104 mapping_dest += PAGE_SIZE;
106 // Roll on to next block if needed
107 if(pagenum - pb->BaseOffset == MMAP_PAGES_PER_BLOCK)
109 if( pb->Next && pb->Next->BaseOffset == pagenum )
113 tVFS_MMapPageBlock *oldpb = pb;
114 pb = malloc( sizeof(tVFS_MMapPageBlock) );
115 pb->Next = oldpb->Next;
116 pb->BaseOffset = pagenum;
117 memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
128 int VFS_MUnmap(void *Addr, size_t Length)