#include <System/Mem.h>
#include <kern/kernel.h>
+
#include <arch/mem.h>
#include <arch/addrs.h>
// other flags are undefined, and pagein() should be retried.
// rmap_lock must be held.
- virtual void get_entry(u64 vaddr, u64 *phys, PTEFlags *flags) = 0;
+ virtual void get_mapping(u64 vaddr, u64 *phys, PTEFlags *flags) = 0;
#include <servers/mem/addrspace/Mem/Mappable.h>
}
};
- // If the padded size of this changes, update rmap_shift.
- // and the alignment check in RMapTable::unmap.
-
- // If the layout of this changes, update the offsets below.
- union RMapNode {
- struct {
- u64 vaddr;
- VirtualArea *va;
- Util::ListNoAutoInit head, tail;
- };
-
- long pad[8];
-
- enum {
- head_offset = sizeof(u64) + sizeof(void *),
- tail_offset = head_offset + sizeof(void *) * 2,
- };
- };
-
- // This lock protects the rmap chains and rmap tables. It also makes
- // atomic the PageTable::get_entry, RMapTable::map, PageTable::map
- // sequence.
- //
- // OPT: This lock is acquired on all map/unmap activity; if/when this
- // turns out to be a significant bottleneck, finer-grained locking can
- // be used. I decided against doing it now because it would be
- // somewhat complicated (but I believe do-able) to avoid all races,
- // and I'd like to move on to implementing other things for now.
-
- extern Lock::Lock rmap_lock;
- class Page;
-
- class RMapTable {
- void *toplevel;
- int toplevel_shift;
-
- RMapNode *get_rmap(u64 virtaddr, bool add = false);
-
- public:
- RMapTable();
-
- // rmap_lock must be held.
- static void map(VirtualArea *downstream_va, PageTable *upstream_ptbl,
- u64 virtaddr, u64 upstream_vaddr);
-
- void unmap(u64 virtaddr);
-
- // Handle a copy-on-write for the specified page and all downstream
- // mappings. All such mappings are set to the new page, and
- // FaultOnWrite is cleared.
-
- void break_copy_on_write(u64 virtaddr, Page *new_page);
- };
-
- class PageTable {
- public:
- void *toplevel;
- RMapTable rmap_table;
- const bool is_process;
-
- typedef Mem::PTEFlags Flags;
- typedef System::Mem::Region Region;
- typedef System::Mem::RegionWithOffset RegionWithOffset;
-
- PageTable(bool process) : is_process(process)
- {
- }
-
- virtual ~PageTable()
- {
- }
-
- // Region is virtual, offset is physical
- virtual void map(RegionWithOffset region, Flags flags) = 0;
- virtual void unmap(Region region) = 0;
-
- // Sets the flags which are set in mask to their value in flags.
- // Flags not set in mask are untouched.
-
- virtual void set_flags(Region region, Flags flags, Flags mask) = 0;
-
- // Returns the physical address and flags associated with a given
- // virtual address. If flags.Valid is not set, then phys and all
- // other flags are undefined. This function is mainly used for
- // propagating stacked aspace PTEs.
-
- virtual void get_entry(u64 vaddr, u64 *phys, Flags *flags) = 0;
-
- virtual void get_size(u64 *size) = 0;
-
- // This is called when a PTE is replaced. It handles refcounting,
- // dirty page queueing, and TLB invalidation. vaddr is only
- // valid for process address spaces, so it doesn't need to be
- // 64-bit (except on 64-bit hardware, of course). When it is
- // known that only flags are changing, set no_release so that
- // the page refcount is not decremented.
-
- void kill_pte(ulong vaddr, u64 physaddr, bool dirty, bool valid,
- bool no_release = false);
- };
struct BadPageFault {
};
// Unexported
virtual void pagein(u64 vaddr, PTEFlags reqflags);
- virtual void get_entry(u64 vaddr, u64 *phys, PTEFlags *flags);
+ virtual void get_mapping(u64 vaddr, u64 *phys, PTEFlags *flags);
friend class AddrSpace;
};
VirtualAreaTree varea_tree;
Util::List varea_list;
Lock::Lock lock;
- bool is_process;
+
// This defines the start and end of the aspace; mappings outside
// this range may not be done, and will not be returned by
// get_free_region(). For process aspaces, this goes from
void break_copy_on_write(VirtualArea *va, u64 vaddr, u64 phys);
bool map(VirtualArea *va, u64 vaddr, PTEFlags reqflags);
+ protected:
+ bool is_process;
+
public:
#include <servers/mem/addrspace/Mem/AddrSpace.h>
ASpaceMappable mappable;
PageTable *page_table;
- AddrSpace(bool process);
- AddrSpace(void *page_table);
+ AddrSpace(PageTable *ptbl = NULL);
// Returns true if the fault was "good"; otherwise, the caller
// should dump regs. exec should only be used if the CPU
void get_mappable(IMappable *ma);
void clone(IAddrSpace *addrspace, u8 clone_is_real);
- void alloc_and_map(u64 len, u64 *vstart,
- AllocFlags aflags, MapFlags mflags);
-
enum {
map_user,
map_protected,
};
void map(IMappable ma, Region region, u64 *vstart, MapFlags mflags,
- bool from_kernel = false, int map_type = map_user);
+ int map_type = map_user);
void unmap(Region region, bool from_kernel = false);
void set_mapflags(Region region, MapFlags mflags);
void get_page_size(u32 *page_size);
void get_min_align(u32 *min_align);
-
- void get_size(u64 *size)
- {
- page_table->get_size(size);
- }
-
- friend void Arch::set_aspace(AddrSpace *aspace);
+ void get_size(u64 *size);
+
friend class ASpaceMappable;
};
-
+
extern Factory addr_space_factory, proc_addr_space_factory;
using ::System::RunTime::orbmm;