blob: 4dae3de7b30cc574f9a39808f28c16ff8d5e74bf [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <phys/address-space.h>
// This method is in a separate file and separate GN phys:address-space-map
// static_library() so that its users don't need to link in the bootstrapping
// dependencies if they only need to Map into an existing AddressSpace as in a
// physload module.
fit::result<AddressSpace::MapError> AddressSpace::Map(uint64_t vaddr, uint64_t size, uint64_t paddr,
AddressSpace::MapSettings settings) {
ZX_ASSERT_MSG(vaddr < kLowerVirtualAddressRangeEnd || vaddr >= kUpperVirtualAddressRangeStart,
"virtual address %#" PRIx64 " must be < %#" PRIx64 " or >= %#" PRIx64, vaddr,
kLowerVirtualAddressRangeEnd, kUpperVirtualAddressRangeStart);
bool upper = vaddr >= kUpperVirtualAddressRangeStart;
// Fix-up settings per documented behavior.
if constexpr (!kExecuteOnlyAllowed) {
settings.access.readable |= !settings.access.writable && settings.access.executable;
}
settings.global = upper;
if constexpr (kDualSpaces) {
if (upper) {
return UpperPaging::Map(upper_root_paddr_, paddr_to_io_, permanent_allocator(), state_, vaddr,
size, paddr, settings);
}
}
// See allocator descriptions for the appropriate use-cases.
auto lower_allocator = upper ? permanent_allocator() : temporary_allocator();
return LowerPaging::Map(lower_root_paddr_, paddr_to_io_, lower_allocator, state_, vaddr, size,
paddr, settings);
}