6 extern Static_object<Mapdb> mapdb_mem;
14 Static_object<Mapdb> mapdb_mem;
16 /** Map the region described by "fp_from" of address space "from" into
17 region "fp_to" at offset "offs" of address space "to", updating the
18 mapping database as we do so.
19 @param from source address space
20 @param fp_from_{page, size, write, grant} flexpage description for
21 virtual-address space range in source address space
22 @param to destination address space
23 @param fp_to_{page, size} flexpage descripton for virtual-address
24 space range in destination address space
25 @param offs sender-specified offset into destination flexpage
26 @return IPC error code that describes the status of the operation
28 L4_error __attribute__((nonnull(1, 3)))
29 mem_map(Space *from, L4_fpage const &fp_from,
30 Space *to, L4_fpage const &fp_to, L4_msg_item control)
32 typedef Map_traits<Mem_space> Mt;
34 if (EXPECT_FALSE(fp_from.order() < L4_fpage::Mem_addr::Shift
35 || fp_to.order() < L4_fpage::Mem_addr::Shift))
36 return L4_error::None;
39 Mt::Addr rcv_addr = fp_to.mem_address();
40 Mt::Addr snd_addr = fp_from.mem_address();
41 Mt::Addr offs = Virt_addr(control.address());
43 Mt::Size snd_size = Mt::Size::from_shift(fp_from.order() - L4_fpage::Mem_addr::Shift);
44 Mt::Size rcv_size = Mt::Size::from_shift(fp_to.order() - L4_fpage::Mem_addr::Shift);
46 // calc size in bytes from power of tows
47 snd_addr = snd_addr.trunc(snd_size);
48 rcv_addr = rcv_addr.trunc(rcv_size);
49 Mt::constraint(snd_addr, snd_size, rcv_addr, rcv_size, offs);
52 return L4_error::None;
54 unsigned long del_attribs, add_attribs;
55 Mt::attribs(control, fp_from, &del_attribs, &add_attribs);
57 return map<Mem_space>(mapdb_mem.get(),
60 rcv_addr, control.is_grant(), add_attribs, del_attribs,
61 (Mem_space::Reap_list**)0);
64 /** Unmap the mappings in the region described by "fp" from the address
65 space "space" and/or the address spaces the mappings have been
67 @param space address space that should be flushed
68 @param fp flexpage descriptor of address-space range that should
70 @param me_too If false, only flush recursive mappings. If true,
71 additionally flush the region in the given address space.
72 @param restriction Only flush specific task ID.
73 @param flush_mode determines which access privileges to remove.
74 @return combined (bit-ORed) access status of unmapped physical pages
76 unsigned __attribute__((nonnull(1)))
77 mem_fpage_unmap(Space *space, L4_fpage fp, L4_map_mask mask)
79 typedef Map_traits<Mem_space> Mt;
80 Mt::Size size = Mt::Size::from_shift(fp.order() - L4_fpage::Mem_addr::Shift);
81 Mt::Addr start = Mt::get_addr(fp);
83 start = start.trunc(size);
85 return unmap<Mem_space>(mapdb_mem.get(), space, space,
87 fp.rights(), mask, (Mem_space::Reap_list**)0);
92 save_access_attribs(Mapdb* mapdb, const Mapdb::Frame& mapdb_frame,
93 Mapping* mapping, Mem_space* space, unsigned page_rights,
94 Mem_space::Addr virt, Mem_space::Phys_addr phys,
98 typedef Mem_space::Size Size;
99 typedef Mem_space::Addr Addr;
100 typedef Mem_space::Phys_addr Phys_addr;
102 if (unsigned page_accessed
103 = page_rights & (Mem_space::Page_referenced | Mem_space::Page_dirty))
105 Mem_space::Status status;
107 // When flushing access attributes from our space as well,
108 // cache them in parent space, otherwise in our space.
109 if (! me_too || !mapping->parent())
111 status = space->v_insert(phys, virt, size,
116 Mapping *parent = mapping->parent();
118 assert (parent->space());
119 Mem_space *parent_space = parent->space();
121 Address parent_shift = mapdb->shift(mapdb_frame, parent) + Mem_space::Page_shift;
122 Address parent_address = parent->page().value() << parent_shift;
125 parent_space->v_insert(phys.trunc(Phys_addr::create(1UL << parent_shift)),
126 Addr::create(parent_address),
127 Size::create(1UL << parent_shift),
128 page_accessed, true);
131 assert (status == Mem_space::Insert_ok
132 || status == Mem_space::Insert_warn_exists
133 || status == Mem_space::Insert_warn_attrib_upgrade
134 /*|| s->is_sigma0()*/);
135 // Be forgiving to sigma0 because it's address
136 // space is not kept in sync with its mapping-db
141 //---------------------------------------------------------------------------
142 IMPLEMENTATION[!64bit]:
144 /** The mapping database.
145 This is the system's instance of the mapping database.
148 init_mapdb_mem(Space *sigma0)
150 static size_t const page_sizes[]
151 = { Config::SUPERPAGE_SHIFT - Config::PAGE_SHIFT, 0 };
153 mapdb_mem.construct(sigma0,
154 Page_number::create(1U << (32 - Config::SUPERPAGE_SHIFT)),
158 //---------------------------------------------------------------------------
159 IMPLEMENTATION[amd64]:
163 /** The mapping database.
164 This is the system's instance of the mapping database.
167 init_mapdb_mem(Space *sigma0)
169 static size_t const amd64_page_sizes[] =
170 { Config::PML4E_SHIFT - Config::PAGE_SHIFT,
171 Config::PDPE_SHIFT - Config::PAGE_SHIFT,
172 Config::SUPERPAGE_SHIFT - Config::PAGE_SHIFT,
175 unsigned const num_page_sizes = Cpu::boot_cpu()->phys_bits() >= 42 ? 4 : 3;
177 Address const largest_page_max_index = num_page_sizes == 4 ?
178 Config::PML4E_MASK + 1ULL
179 : 1ULL << (Cpu::boot_cpu()->phys_bits() - Config::PDPE_SHIFT);
181 size_t const *const page_sizes = num_page_sizes == 4 ? amd64_page_sizes : amd64_page_sizes + 1;
183 mapdb_mem.construct(sigma0, Page_number::create(largest_page_max_index),
184 page_sizes, num_page_sizes);