6 /** Map the region described by "fp_from" of address space "from" into
7 region "fp_to" at offset "offs" of address space "to", updating the
8 mapping database as we do so.
9 @param from source address space
10 @param fp_from_{page, size, write, grant} flexpage description for
11 virtual-address space range in source address space
12 @param to destination address space
13 @param fp_to_{page, size} flexpage descripton for virtual-address
14 space range in destination address space
15 @param offs sender-specified offset into destination flexpage
16 @return IPC error code that describes the status of the operation
19 mem_map(Space *from, L4_fpage const &fp_from,
20 Space *to, L4_fpage const &fp_to, L4_msg_item control)
22 typedef Map_traits<Mem_space> Mt;
24 if (EXPECT_FALSE(fp_from.order() < L4_fpage::Mem_addr::Shift
25 || fp_to.order() < L4_fpage::Mem_addr::Shift))
26 return L4_error::None;
29 Mt::Addr rcv_addr = fp_to.mem_address();
30 Mt::Addr snd_addr = fp_from.mem_address();
31 Mt::Addr offs = Virt_addr(control.address());
33 Mt::Size snd_size = Mt::Size::from_shift(fp_from.order() - L4_fpage::Mem_addr::Shift);
34 Mt::Size rcv_size = Mt::Size::from_shift(fp_to.order() - L4_fpage::Mem_addr::Shift);
36 // calc size in bytes from power of tows
37 snd_addr = snd_addr.trunc(snd_size);
38 rcv_addr = rcv_addr.trunc(rcv_size);
39 Mt::constraint(snd_addr, snd_size, rcv_addr, rcv_size, offs);
43 if (Config::conservative)
44 kdb_ke("fpage transfer = nop");
45 return L4_error::None;
48 unsigned long del_attribs, add_attribs;
49 Mt::attribs(control, fp_from, &del_attribs, &add_attribs);
51 return map(mapdb_instance(),
52 from->mem_space(), from, snd_addr,
53 snd_size, to->mem_space(), to,
54 rcv_addr, control.is_grant(), add_attribs, del_attribs,
55 (Mem_space::Reap_list**)0);
58 /** Unmap the mappings in the region described by "fp" from the address
59 space "space" and/or the address spaces the mappings have been
61 @param space address space that should be flushed
62 @param fp flexpage descriptor of address-space range that should
64 @param me_too If false, only flush recursive mappings. If true,
65 additionally flush the region in the given address space.
66 @param restriction Only flush specific task ID.
67 @param flush_mode determines which access privileges to remove.
68 @return combined (bit-ORed) access status of unmapped physical pages
71 mem_fpage_unmap(Space *space, L4_fpage fp, L4_map_mask mask)
73 typedef Map_traits<Mem_space> Mt;
74 Mt::Size size = Mt::Size::from_shift(fp.order() - L4_fpage::Mem_addr::Shift);
75 Mt::Addr start = Mt::get_addr(fp);
77 start = start.trunc(size);
79 return unmap(mapdb_instance(), space->mem_space(), space,
81 fp.rights(), mask, (Mem_space::Reap_list**)0);
86 save_access_attribs(Mapdb* mapdb, const Mapdb::Frame& mapdb_frame,
87 Mapping* mapping, Mem_space* space, unsigned page_rights,
88 Mem_space::Addr virt, Mem_space::Phys_addr phys,
92 typedef Mem_space::Size Size;
93 typedef Mem_space::Addr Addr;
94 typedef Mem_space::Phys_addr Phys_addr;
96 if (unsigned page_accessed
97 = page_rights & (Mem_space::Page_referenced | Mem_space::Page_dirty))
99 Mem_space::Status status;
102 // When flushing access attributes from our space as well,
103 // cache them in parent space, otherwise in our space.
104 if (! me_too || !mapping->parent())
106 status = space->v_insert(phys, virt, size,
113 Mapping *parent = mapping->parent();
115 Mem_space *parent_space = parent->space()->mem_space();
117 Address parent_shift = mapdb->shift(mapdb_frame, parent) + Mem_space::Page_shift;
118 Address parent_address = parent->page().value() << parent_shift;
121 parent_space->v_insert(phys.trunc(Phys_addr::create(1UL << parent_shift)),
122 Addr::create(parent_address),
123 Size::create(1UL << parent_shift),
124 page_accessed, true);
129 assert (status == Mem_space::Insert_ok
130 || status == Mem_space::Insert_warn_exists
131 || status == Mem_space::Insert_warn_attrib_upgrade
133 // Be forgiving to sigma0 because it's address
134 // space is not kept in sync with its mapping-db
140 // Mapdb instance for memory mappings
143 Mapdb *mapdb_instance() FIASCO_CONST;
145 //---------------------------------------------------------------------------
146 IMPLEMENTATION[!64bit]:
148 /** The mapping database.
149 This is the system's instance of the mapping database.
154 static const size_t page_sizes[]
155 = { Config::SUPERPAGE_SHIFT - Config::PAGE_SHIFT, 0 };
157 static Mapdb mapdb(sigma0_task,
158 Page_number::create(1U << (32 - Config::SUPERPAGE_SHIFT)),
164 //---------------------------------------------------------------------------
165 IMPLEMENTATION[amd64]:
169 /** The mapping database.
170 This is the system's instance of the mapping database.
175 static const size_t amd64_page_sizes[] =
176 { Config::PML4E_SHIFT - Config::PAGE_SHIFT,
177 Config::PDPE_SHIFT - Config::PAGE_SHIFT,
178 Config::SUPERPAGE_SHIFT - Config::PAGE_SHIFT,
181 static const unsigned num_page_sizes = Cpu::boot_cpu()->phys_bits() >= 42 ? 4 : 3;
183 static const Address largest_page_max_index = num_page_sizes == 4 ?
184 Config::PML4E_MASK + 1ULL
185 : 1ULL << (Cpu::boot_cpu()->phys_bits() - Config::PDPE_SHIFT);
187 static const size_t* page_sizes = num_page_sizes == 4 ?
188 amd64_page_sizes : amd64_page_sizes + 1;
190 static Mapdb mapdb((Space*)sigma0_task,
191 Page_number::create(largest_page_max_index),
192 page_sizes, num_page_sizes);