X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/013297c0d65e3dab85bb75c5a104babaebedd230..56a09572268504317eb2885b827f9c4378071a7c:/kernel/fiasco/src/test/unit/map_util_t.cpp diff --git a/kernel/fiasco/src/test/unit/map_util_t.cpp b/kernel/fiasco/src/test/unit/map_util_t.cpp index 7f03fe232..d3f73d1f7 100644 --- a/kernel/fiasco/src/test/unit/map_util_t.cpp +++ b/kernel/fiasco/src/test/unit/map_util_t.cpp @@ -23,7 +23,6 @@ using namespace std; #include "static_init.h" #include "usermode.h" #include "vmem_alloc.h" -#include "mem_space_sigma0.h" IMPLEMENTATION: @@ -32,17 +31,50 @@ typedef L4_fpage Test_fpage; class Test_space : public Space { public: - Test_space (Ram_quota *rq) - : Space (Space::Default_factory(), rq, L4_fpage::mem(0x1200000, Config::PAGE_SHIFT)) - {} + Test_space(Ram_quota *rq, char const *name) + : Space(rq, Caps::all()), name(name) + { + initialize(); + } void* operator new (size_t s) { return malloc (s); } void operator delete (void *p) { ::free (p); } + + char const *const name; +}; + +class Sigma0_space : public Test_space +{ +public: + explicit Sigma0_space(Ram_quota *q) : Test_space(q, "s0") {} + bool is_sigma0() const { return true; } }; + +PUBLIC +bool +Sigma0_space::v_fabricate(Mem_space::Vaddr address, + Mem_space::Phys_addr *phys, Mem_space::Page_order *size, + Mem_space::Attr *attribs = 0) +{ + // special-cased because we don't do ptab lookup for sigma0 + *size = static_cast(*this).largest_page_size(); + *phys = cxx::mask_lsb(Virt_addr(address), *size); + + if (attribs) + *attribs = Mem_space::Attr(L4_fpage::Rights::URWX()); + + return true; +} + +PUBLIC inline +Page_number +Sigma0_space::mem_space_map_max_address() const +{ return Page_number(1UL << (MWORD_BITS - Mem_space::Page_shift)); } + class Timeout; DEFINE_PER_CPU Per_cpu timeslice_timeout; @@ -51,18 +83,18 @@ STATIC_INITIALIZER_P(init2, POST_CPU_LOCAL_INIT_PRIO); static void init() { - Usermode::init(0); + Usermode::init(Cpu_number::boot_cpu()); Boot_info::init(); - Kip_init::setup_ux(); - Kmem_alloc::base_init(); Kip_init::init(); + Kmem_alloc::base_init(); Kmem_alloc::init(); // Initialize cpu-local data management and run constructors for CPU 0 Per_cpu_data::init_ctors(); - Per_cpu_data_alloc::alloc(0); - Per_cpu_data::run_ctors(0); + Per_cpu_data_alloc::alloc(Cpu_number::boot_cpu()); + Per_cpu_data::run_ctors(Cpu_number::boot_cpu()); + Mem_space::init_page_sizes(); } static void init2() @@ -70,182 +102,180 @@ static void init2() Cpu::init_global_features(); Config::init(); Kmem::init_mmu(*Cpu::boot_cpu()); - Vmem_alloc::init(); Pic::init(); } -static Ram_quota rq; - -struct Sigma0_space_factory +class Fake_factory : public Ram_quota { - static void create(Mem_space *v, Ram_quota *q) - { new (v) Mem_space_sigma0(q); } +}; - template< typename S > - static void create(S *v) - { new (v) S(); } +extern Static_object mapdb_mem; +static Fake_factory rq; -}; +static +Mem_space *ms(Space *s) { return s; } + +static +Mem_space::Vaddr +to_vaddr(Address a) +{ return Mem_space::Vaddr(Virt_addr(a)); } + +static +Mapdb::Pfn to_pfn(Address a) +{ return Mem_space::to_pfn(Virt_addr(a)); } int main() { - // - // Create tasks - // - Space *sigma0 = new Space (Sigma0_space_factory(), &rq, L4_fpage::mem(0x1200000, Config::PAGE_SHIFT)); + cout << "[UTEST] *** Create tasks ***" << endl; + + Space *sigma0 = new Sigma0_space(&rq); init_mapdb_mem(sigma0); - Test_space *server = new Test_space (&rq); + Test_space *server = new Test_space (&rq, "server"); assert (server); - Test_space *client = new Test_space (&rq); + Test_space *client = new Test_space (&rq, "client"); assert (client); - Test_space *client2 = new Test_space (&rq); + Test_space *client2 = new Test_space (&rq, "client2"); assert (client2); - // - // Manipulate mappings. - // - Mapdb* mapdb = mapdb_instance(); + cout << "[UTEST] *** Manipulate mappings ***" << endl; + + Mapdb* mapdb = mapdb_mem.get(); - Mem_space::Phys_addr phys; - Virt_size size; - unsigned page_attribs; + typedef Mem_space::Page_order Page_order; + typedef Mem_space::Phys_addr Phys_addr; + typedef Mem_space::Attr Attr;; + + Phys_addr phys; + Page_order order; + Attr page_attribs; Mapping *m; Mapdb::Frame frame; - - // - // s0 [0x10000] -> server [0x1000] - // - assert (server->mem_space()->v_lookup (Virt_addr(0x1000), &phys, &size, &page_attribs) + + cout << "[UTEST] s0 [0x10000] -> server [0x1000]" << endl; + + assert (ms(server)->v_lookup(to_vaddr(0x1000), &phys, &order, &page_attribs) == false); Reap_list reap; - fpage_map (sigma0, - Test_fpage::mem(0x10000, Config::PAGE_SHIFT, L4_fpage::RWX), - server, - L4_fpage::all_spaces(), - 0x1000, &reap); + fpage_map(sigma0, + Test_fpage::mem(0x10000, Config::PAGE_SHIFT, L4_fpage::Rights::URWX()), + server, + L4_fpage::all_spaces(), + L4_msg_item(0x1000), &reap); - assert (server->mem_space()->v_lookup (Virt_addr(0x1000), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0x1000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); - assert (phys == Virt_addr(0x10000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); + assert (order == Page_order(Config::PAGE_SHIFT)); + assert (phys == Phys_addr(0x10000)); + assert (page_attribs.rights == L4_fpage::Rights::URWX()); - assert (mapdb->lookup (sigma0, Virt_addr(0x10000), Virt_addr(0x10000), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0x10000), to_pfn(0x10000), &m, &frame)); print_node (m, frame); mapdb->free (frame); - // - // s0 [0/superpage] -> server [0] -> should map many 4K pages and - // overmap previous mapping - // - assert (server->mem_space()->v_lookup (Virt_addr(0), &phys, &size, &page_attribs) + cout << "[UTEST] s0 [0/superpage] -> server [0] -> should map many 4K pages and " + "overmap previous mapping" << endl; + + assert (ms(server)->v_lookup(to_vaddr(0), &phys, &order, &page_attribs) == false); - fpage_map (sigma0, - L4_fpage::mem(0, Config::SUPERPAGE_SHIFT, L4_fpage::RX), - server, - L4_fpage::all_spaces(), - 0, &reap); + fpage_map(sigma0, + L4_fpage::mem(0, Config::SUPERPAGE_SHIFT, L4_fpage::Rights::URX()), + server, + L4_fpage::all_spaces(), + L4_msg_item(0), &reap); - assert (server->mem_space()->v_lookup (Virt_addr(0), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); // and not SUPERPAGE_SIZE! - assert (phys == Virt_addr(0)); - assert (page_attribs == Mem_space::Page_user_accessible); + assert (order == Page_order(Config::PAGE_SHIFT)); // and not SUPERPAGE_SIZE! + assert (phys == Phys_addr(0)); + assert (page_attribs.rights == L4_fpage::Rights::URX()); - assert (mapdb->lookup (sigma0, Virt_addr(0), Virt_addr(0), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0), to_pfn(0), &m, &frame)); print_node (m, frame); mapdb->free (frame); // previous mapping still there? - assert (server->mem_space()->v_lookup (Virt_addr(0x1000), &phys, &size, &page_attribs) - == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (ms(server)->v_lookup(to_vaddr(0x1000), &phys, &order, &page_attribs)); + assert (order == Page_order(Config::PAGE_SHIFT)); // Previously, overmapping did not work and was ignored, so the // lookup yielded the previously established mapping: // assert (phys == 0x10000); // assert (page_attribs == (Mem_space::Page_writable | Mem_space::Page_user_accessible)); // Now, the previous mapping should have been overwritten: - assert (phys == Virt_addr(0x1000)); - assert (page_attribs == Mem_space::Page_user_accessible); + assert (phys == Phys_addr(0x1000)); + assert (page_attribs.rights == L4_fpage::Rights::URX()); // mapdb entry -- tree should now contain another mapping // s0 [0x10000] -> server [0x10000] - assert (mapdb->lookup (sigma0, Virt_addr(0x10000), Virt_addr(0x10000), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0x10000), to_pfn(0x10000), &m, &frame)); print_node (m, frame, 0x10000, 0x11000); mapdb->free (frame); - // - // Partially unmap superpage s0 [0/superpage] - // - assert (server->mem_space()->v_lookup (Virt_addr(0x101000), &phys, &size, &page_attribs) + cout << "[UTEST] Partially unmap superpage s0 [0/superpage]" << endl; + + assert (ms(server)->v_lookup(to_vaddr(0x101000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); - assert (phys == Virt_addr(0x101000)); - assert (page_attribs == Mem_space::Page_user_accessible); + assert (order == Page_order(Config::PAGE_SHIFT)); + assert (phys == Phys_addr(0x101000)); + assert (page_attribs.rights == L4_fpage::Rights::URX()); - fpage_unmap (sigma0, - Test_fpage::mem(0x100000, Config::SUPERPAGE_SHIFT - 2, L4_fpage::RWX), - L4_map_mask(0) /*full unmap, not me too)*/, reap.list()); + fpage_unmap(sigma0, + Test_fpage::mem(0x100000, Config::SUPERPAGE_SHIFT - 2, L4_fpage::Rights::URWX()), + L4_map_mask(0) /*full unmap, not me too)*/, reap.list()); - assert (mapdb->lookup (sigma0, Virt_addr(0x0), Virt_addr(0x0), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0x0), to_pfn(0x0), &m, &frame)); print_node (m, frame); mapdb->free (frame); - - assert (! server->mem_space()->v_lookup (Virt_addr(0x101000), &phys, &size, - &page_attribs) - == true); + + assert (! ms(server)->v_lookup(to_vaddr(0x101000), &phys, &order, &page_attribs)); // // s0 [4M/superpage] -> server [8M] // - assert (server->mem_space()->v_lookup (Virt_addr(0x800000), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0x800000), &phys, &order, &page_attribs) == false); - fpage_map (sigma0, - Test_fpage::mem(0x400000, Config::SUPERPAGE_SHIFT, L4_fpage::RWX), - server, - L4_fpage::mem(0x800000, Config::SUPERPAGE_SHIFT), - 0, &reap); + fpage_map(sigma0, + Test_fpage::mem(0x400000, Config::SUPERPAGE_SHIFT, L4_fpage::Rights::URWX()), + server, + L4_fpage::mem(0x800000, Config::SUPERPAGE_SHIFT), + L4_msg_item(0), &reap); - assert (server->mem_space()->v_lookup (Virt_addr(0x800000), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0x800000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::SUPERPAGE_SIZE)); + assert (order == Page_order(Config::SUPERPAGE_SHIFT)); assert (phys == Virt_addr(0x400000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); + assert (page_attribs.rights == L4_fpage::Rights::URWX()); - assert (mapdb->lookup (sigma0, Virt_addr(0x400000), Virt_addr(0x400000), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0x400000), to_pfn(0x400000), &m, &frame)); print_node (m, frame); mapdb->free (frame); // // server [8M+4K] -> client [8K] // - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == false); - fpage_map (server, - Test_fpage::mem(0x801000, Config::PAGE_SHIFT, L4_fpage::RWX), - client, - L4_fpage::mem(0, L4_fpage::Whole_space), - 0x8000, &reap); + fpage_map(server, + Test_fpage::mem(0x801000, Config::PAGE_SHIFT, L4_fpage::Rights::URWX()), + client, + L4_fpage::mem(0, L4_fpage::Whole_space), + L4_msg_item(0x8000), &reap); - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (order == Page_order(Config::PAGE_SHIFT)); assert (phys == Virt_addr(0x401000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); + assert (page_attribs.rights == L4_fpage::Rights::URWX()); // Previously, the 4K submapping is attached to the Sigma0 parent. // Not any more. - assert (mapdb->lookup (sigma0, Virt_addr(0x400000), Virt_addr(0x400000), &m, &frame)); + assert (mapdb->lookup(sigma0, to_pfn(0x400000), to_pfn(0x400000), &m, &frame)); print_node (m, frame); mapdb->free (frame); @@ -253,18 +283,17 @@ int main() // Overmap a read-only page. The writable attribute should not be // flushed. // - fpage_map (server, - Test_fpage::mem(0x801000, Config::PAGE_SHIFT, L4_fpage::RX), - client, - L4_fpage::mem(0, L4_fpage::Whole_space), - 0x8000, &reap); + fpage_map(server, + Test_fpage::mem(0x801000, Config::PAGE_SHIFT, L4_fpage::Rights::URX()), + client, + L4_fpage::mem(0, L4_fpage::Whole_space), + L4_msg_item(0x8000), &reap); - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (order == Page_order(Config::PAGE_SHIFT)); assert (phys == Virt_addr(0x401000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); + assert (page_attribs.rights == L4_fpage::Rights::URWX()); #if 0 // no selective unmap anymore // @@ -306,7 +335,6 @@ int main() print_node (m, frame); mapdb->free (frame); #endif - cerr << "... "; // @@ -314,68 +342,51 @@ int main() // // touch page in client - assert (client->mem_space()->v_insert (Virt_addr(0x401000), Virt_addr(0x8000), Virt_size(Config::PAGE_SIZE), - Mem_space::Page_dirty | Mem_space::Page_referenced) - == Mem_space::Insert_warn_attrib_upgrade); + ms(client)->v_set_access_flags(to_vaddr(0x8000), L4_fpage::Rights::RW()); - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (order == Page_order(Config::PAGE_SHIFT)); assert (phys == Virt_addr(0x401000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible - | Mem_space::Page_dirty | Mem_space::Page_referenced)); + assert (page_attribs.rights == L4_fpage::Rights::URWX()); + // the next would reset flags, so don't do it!! + // assert (ms(client)->v_delete(to_vaddr(0x8000), order, L4_fpage::Rights(0)) == L4_fpage::Rights::RW()); + // reset dirty from server - assert (fpage_unmap (server, - Test_fpage::mem(0x801000, Config::PAGE_SHIFT), - L4_map_mask(0), reap.list() - /*no_unmap + reset_refs*/) - == Mem_space::Page_referenced | Mem_space::Page_dirty); + assert (fpage_unmap(server, + Test_fpage::mem(0x801000, Config::PAGE_SHIFT), + L4_map_mask(0), reap.list() + /*no_unmap + reset_refs*/) + == L4_fpage::Rights::RW()); - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (order == Page_order(Config::PAGE_SHIFT)); assert (phys == Virt_addr(0x401000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); // Page_dirty | Page_referecned is gone... + assert (ms(client)->v_delete(to_vaddr(0x8000), order, L4_fpage::Rights(0)) == L4_fpage::Rights(0)); - assert (server->mem_space()->v_lookup (Virt_addr(0x801000), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0x801000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::SUPERPAGE_SIZE)); + assert (order == Page_order(Config::SUPERPAGE_SHIFT)); assert (phys == Virt_addr(0x400000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible - | Mem_space::Page_dirty | Mem_space::Page_referenced)); // ...and went here // flush dirty and accessed from server - assert (fpage_unmap (server, - Test_fpage::mem(0x800000, Config::SUPERPAGE_SHIFT), - L4_map_mask(0x80000000), reap.list()) - == Mem_space::Page_dirty | Mem_space::Page_referenced); + assert (fpage_unmap(server, + Test_fpage::mem(0x800000, Config::SUPERPAGE_SHIFT), + L4_map_mask(0x80000000), reap.list()) + == L4_fpage::Rights::RW()); - assert (client->mem_space()->v_lookup (Virt_addr(0x8000), &phys, &size, &page_attribs) + assert (ms(client)->v_lookup(to_vaddr(0x8000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::PAGE_SIZE)); + assert (order == Page_order(Config::PAGE_SHIFT)); assert (phys == Virt_addr(0x401000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); // dirty/ref gone - - assert (server->mem_space()->v_lookup (Virt_addr(0x800000), &phys, &size, &page_attribs) - == true); - assert (size == Virt_size(Config::SUPERPAGE_SIZE)); - assert (phys == Virt_addr(0x400000)); - assert (page_attribs == (Mem_space::Page_writable - | Mem_space::Page_user_accessible)); // dirty/ref gone + assert (ms(client)->v_delete(to_vaddr(0x8000), order, L4_fpage::Rights(0)) == L4_fpage::Rights(0)); - assert (sigma0->mem_space()->v_lookup (Virt_addr(0x400000), &phys, &size, &page_attribs) + assert (ms(server)->v_lookup(to_vaddr(0x800000), &phys, &order, &page_attribs) == true); - assert (size == Virt_size(Config::SUPERPAGE_SIZE)); + assert (order == Page_order(Config::SUPERPAGE_SHIFT)); assert (phys == Virt_addr(0x400000)); - // Be a bit more lax in checking Sigma0's address space: It does - // not contain Page_writable / Page_user_accessible flags unless - // they are faulted in. - assert (page_attribs & (Mem_space::Page_dirty | Mem_space::Page_referenced)); - + assert (page_attribs.rights == L4_fpage::Rights::URWX()); // // Delete tasks @@ -394,27 +405,55 @@ int main() return 0; } + +static +std::ostream &operator << (std::ostream &s, Mapdb::Pfn v) +{ + s << cxx::int_value(v); + return s; +} + +static +std::ostream &operator << (std::ostream &s, Mapping::Page v) +{ + s << cxx::int_value(v); + return s; +} + +static +std::ostream &operator << (std::ostream &s, Space const &sp) +{ + Test_space const *t = static_cast(&sp); + if (!t) + s << ""; + else + s << t->name; + return s; +} + + static void print_node(Mapping* node, const Mapdb::Frame& frame, Address va_begin = 0, Address va_end = ~0UL) { assert (node); - size_t size = Mapdb::shift(frame, node); + Mapdb::Order size = Mapdb::shift(frame, node); - for (Mapdb::Iterator i (frame, node, Virt_addr(va_begin), Virt_addr(va_end)); node;) + for (Mapdb::Iterator i (frame, node, to_pfn(va_begin), to_pfn(va_end)); node;) { + cout << "[UTEST] "; for (int d = node->depth(); d != 0; d--) cout << ' '; cout << setbase(16) - << "space=0x" << (unsigned long) (node->space()) - << " vaddr=0x" << node->page() << size - << " size=0x" << size; + << "space=" << *node->space() + << " vaddr=0x" << (node->page() << size) + << " size=0x" << (Mapdb::Pfn(1) << size); if (Mapping* p = node->parent()) { - cout << " parent=0x" << (unsigned long)p->space() - << " p.vaddr=0x" << p->page().value() << size; + cout << " parent=" << *p->space() + << " p.vaddr=0x" << (p->page() << size); } cout << endl; @@ -422,10 +461,10 @@ static void print_node(Mapping* node, const Mapdb::Frame& frame, node = i; if (node) { - size = i.shift(); + size = i.order(); ++i; } } - cout << endl; + cout << "[UTEST] " << endl; }