/*
- * Acess2 VFS
- * - Open, Close and ChDir
+ * Acess2 Kernel VFS
+ * - By John Hodge (thePowersGang)
+ *
+ * mmap.c
+ * - VFS_MMap support
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <vfs.h>
#include <vfs_ext.h>
ENTER("pDestHint iLength xProtection xFlags xFD XOffset", DestHint, Length, Protection, Flags, FD, Offset);
+ if( Flags & MMAP_MAP_ANONYMOUS )
+ Offset = (tVAddr)DestHint & 0xFFF;
+
npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
pagenum = Offset / PAGE_SIZE;
// Handle anonymous mappings
if( Flags & MMAP_MAP_ANONYMOUS )
{
- for( ; npages --; mapping_dest += PAGE_SIZE )
+ size_t ofs = 0;
+ LOG("%i pages anonymous to %p", npages, mapping_dest);
+ for( ; npages --; mapping_dest += PAGE_SIZE, ofs += PAGE_SIZE )
{
if( MM_GetPhysAddr(mapping_dest) ) {
// TODO: Set flags to COW if needed (well, if shared)
+ MM_SetFlags(mapping_dest, MM_PFLAG_COW, MM_PFLAG_COW);
+ LOG("clear from %p, %i bytes", (void*)(mapping_base + ofs),
+ PAGE_SIZE - (mapping_base & (PAGE_SIZE-1))
+ );
+ memset( (void*)(mapping_base + ofs), 0, PAGE_SIZE - (mapping_base & (PAGE_SIZE-1)));
}
else {
+ LOG("New empty page");
+ // TODO: Map a COW zero page instead
if( !MM_Allocate(mapping_dest) ) {
// TODO: Error
Log_Warning("VFS", "VFS_MMap: Anon alloc to %p failed", mapping_dest);
}
+ memset((void*)mapping_dest, 0, PAGE_SIZE);
LOG("Anon map to %p", mapping_dest);
}
}
h->Node->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
else
{
+ int read_len;
// Allocate pages and read data
if( MM_Allocate(mapping_dest) == 0 ) {
// TODO: Unwrap
LEAVE('n');
return NULL;
}
- h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
+ // TODO: Clip read length
+ read_len = h->Node->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, (void*)mapping_dest);
+// if( read_len != PAGE_SIZE ) {
+// memset( (void*)(mapping_dest+read_len), 0, PAGE_SIZE-read_len );
+// }
}
pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
MM_SetPageNode( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node );
+ MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
LOG("Read and map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
pb->PhysAddrs[pagenum - pb->BaseOffset]);
}
else
{
MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
+ MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
LOG("Cached map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
pb->PhysAddrs[pagenum - pb->BaseOffset]);
}
else {
MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
}
+
+ if( Protection & MMAP_PROT_EXEC ) {
+ MM_SetFlags(mapping_dest, MM_PFLAG_EXEC, MM_PFLAG_EXEC);
+ }
+ else {
+ MM_SetFlags(mapping_dest, 0, MM_PFLAG_EXEC);
+ }
}
else
{