Merge "Move memory layout helpers to new module."
diff --git a/vmbase/example/src/layout.rs b/vmbase/example/src/layout.rs
new file mode 100644
index 0000000..9cf1a69
--- /dev/null
+++ b/vmbase/example/src/layout.rs
@@ -0,0 +1,123 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Memory layout.
+
+use aarch64_paging::paging::{MemoryRegion, VirtualAddress};
+use core::ops::Range;
+use vmbase::println;
+
+/// The first 1 GiB of memory are used for MMIO.
+pub const DEVICE_REGION: MemoryRegion = MemoryRegion::new(0, 0x40000000);
+
+/// Memory reserved for the DTB.
+pub fn dtb_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&dtb_begin as *const u8 as usize)
+            ..VirtualAddress(&dtb_end as *const u8 as usize)
+    }
+}
+
+/// Executable code.
+pub fn text_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&text_begin as *const u8 as usize)
+            ..VirtualAddress(&text_end as *const u8 as usize)
+    }
+}
+
+/// Read-only data.
+pub fn rodata_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&rodata_begin as *const u8 as usize)
+            ..VirtualAddress(&rodata_end as *const u8 as usize)
+    }
+}
+
+/// Initialised writable data.
+pub fn data_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&data_begin as *const u8 as usize)
+            ..VirtualAddress(&data_end as *const u8 as usize)
+    }
+}
+
+/// Zero-initialised writable data.
+pub fn bss_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&bss_begin as *const u8 as usize)
+            ..VirtualAddress(&bss_end as *const u8 as usize)
+    }
+}
+
+/// Writable data region for the stack.
+pub fn boot_stack_range() -> Range<VirtualAddress> {
+    unsafe {
+        VirtualAddress(&boot_stack_begin as *const u8 as usize)
+            ..VirtualAddress(&boot_stack_end as *const u8 as usize)
+    }
+}
+
+/// Writable data, including the stack.
+pub fn writable_region() -> MemoryRegion {
+    unsafe {
+        MemoryRegion::new(&data_begin as *const u8 as usize, &boot_stack_end as *const u8 as usize)
+    }
+}
+
+fn data_load_address() -> VirtualAddress {
+    unsafe { VirtualAddress(&data_lma as *const u8 as usize) }
+}
+
+pub fn print_addresses() {
+    let dtb = dtb_range();
+    println!("dtb:        {}..{} ({} bytes)", dtb.start, dtb.end, dtb.end - dtb.start);
+    let text = text_range();
+    println!("text:       {}..{} ({} bytes)", text.start, text.end, text.end - text.start);
+    let rodata = rodata_range();
+    println!("rodata:     {}..{} ({} bytes)", rodata.start, rodata.end, rodata.end - rodata.start);
+    let data = data_range();
+    println!(
+        "data:       {}..{} ({} bytes, loaded at {})",
+        data.start,
+        data.end,
+        data.end - data.start,
+        data_load_address(),
+    );
+    let bss = bss_range();
+    println!("bss:        {}..{} ({} bytes)", bss.start, bss.end, bss.end - bss.start);
+    let boot_stack = boot_stack_range();
+    println!(
+        "boot_stack: {}..{} ({} bytes)",
+        boot_stack.start,
+        boot_stack.end,
+        boot_stack.end - boot_stack.start
+    );
+}
+
+extern "C" {
+    static dtb_begin: u8;
+    static dtb_end: u8;
+    static text_begin: u8;
+    static text_end: u8;
+    static rodata_begin: u8;
+    static rodata_end: u8;
+    static data_begin: u8;
+    static data_end: u8;
+    static data_lma: u8;
+    static bss_begin: u8;
+    static bss_end: u8;
+    static boot_stack_begin: u8;
+    static boot_stack_end: u8;
+}
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index 3a1de08..6b110cf 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -19,13 +19,14 @@
 #![feature(default_alloc_error_handler)]
 
 mod exceptions;
+mod layout;
 
 extern crate alloc;
 
-use aarch64_paging::{
-    idmap::IdMap,
-    paging::{Attributes, MemoryRegion},
+use crate::layout::{
+    dtb_range, print_addresses, rodata_range, text_range, writable_region, DEVICE_REGION,
 };
+use aarch64_paging::{idmap::IdMap, paging::Attributes};
 use alloc::{vec, vec::Vec};
 use buddy_system_allocator::LockedHeap;
 use vmbase::{main, println};
@@ -42,9 +43,6 @@
 
 static mut HEAP: [u8; 65536] = [0; 65536];
 
-/// The first 1 GiB of memory are used for MMIO.
-const DEVICE_REGION: MemoryRegion = MemoryRegion::new(0, 0x40000000);
-
 main!(main);
 
 /// Entry point for VM bootloader.
@@ -52,9 +50,7 @@
     println!("Hello world");
     println!("x0={:#018x}, x1={:#018x}, x2={:#018x}, x3={:#018x}", arg0, arg1, arg2, arg3);
     print_addresses();
-    unsafe {
-        assert_eq!(arg0, &dtb_begin as *const u8 as u64);
-    }
+    assert_eq!(arg0, dtb_range().start.0 as u64);
     check_data();
 
     unsafe {
@@ -67,13 +63,13 @@
     idmap.map_range(&DEVICE_REGION, Attributes::DEVICE_NGNRE | Attributes::EXECUTE_NEVER).unwrap();
     idmap
         .map_range(
-            &text_region(),
+            &text_range().into(),
             Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,
         )
         .unwrap();
     idmap
         .map_range(
-            &rodata_region(),
+            &rodata_range().into(),
             Attributes::NORMAL
                 | Attributes::NON_GLOBAL
                 | Attributes::READ_ONLY
@@ -95,67 +91,6 @@
     check_data();
 }
 
-/// Executable code.
-fn text_region() -> MemoryRegion {
-    unsafe { MemoryRegion::new(&text_begin as *const u8 as usize, &text_end as *const u8 as usize) }
-}
-
-/// Read-only data.
-fn rodata_region() -> MemoryRegion {
-    unsafe {
-        MemoryRegion::new(&rodata_begin as *const u8 as usize, &rodata_end as *const u8 as usize)
-    }
-}
-
-/// Writable data, including the stack.
-fn writable_region() -> MemoryRegion {
-    unsafe {
-        MemoryRegion::new(&data_begin as *const u8 as usize, &boot_stack_end as *const u8 as usize)
-    }
-}
-
-fn print_addresses() {
-    unsafe {
-        println!(
-            "dtb:        {:#010x}-{:#010x} ({} bytes)",
-            &dtb_begin as *const u8 as usize,
-            &dtb_end as *const u8 as usize,
-            &dtb_end as *const u8 as usize - &dtb_begin as *const u8 as usize,
-        );
-        println!(
-            "text:       {:#010x}-{:#010x} ({} bytes)",
-            &text_begin as *const u8 as usize,
-            &text_end as *const u8 as usize,
-            &text_end as *const u8 as usize - &text_begin as *const u8 as usize,
-        );
-        println!(
-            "rodata:     {:#010x}-{:#010x} ({} bytes)",
-            &rodata_begin as *const u8 as usize,
-            &rodata_end as *const u8 as usize,
-            &rodata_end as *const u8 as usize - &rodata_begin as *const u8 as usize,
-        );
-        println!(
-            "data:       {:#010x}-{:#010x} ({} bytes, loaded at {:#010x})",
-            &data_begin as *const u8 as usize,
-            &data_end as *const u8 as usize,
-            &data_end as *const u8 as usize - &data_begin as *const u8 as usize,
-            &data_lma as *const u8 as usize,
-        );
-        println!(
-            "bss:        {:#010x}-{:#010x} ({} bytes)",
-            &bss_begin as *const u8 as usize,
-            &bss_end as *const u8 as usize,
-            &bss_end as *const u8 as usize - &bss_begin as *const u8 as usize,
-        );
-        println!(
-            "boot_stack: {:#010x}-{:#010x} ({} bytes)",
-            &boot_stack_begin as *const u8 as usize,
-            &boot_stack_end as *const u8 as usize,
-            &boot_stack_end as *const u8 as usize - &boot_stack_begin as *const u8 as usize,
-        );
-    }
-}
-
 fn check_data() {
     println!("INITIALISED_DATA: {:#010x}", &INITIALISED_DATA as *const u32 as usize);
     unsafe {
@@ -201,19 +136,3 @@
     assert_eq!(vector[2], 42);
     println!("Vec seems to work.");
 }
-
-extern "C" {
-    static dtb_begin: u8;
-    static dtb_end: u8;
-    static text_begin: u8;
-    static text_end: u8;
-    static rodata_begin: u8;
-    static rodata_end: u8;
-    static data_begin: u8;
-    static data_end: u8;
-    static data_lma: u8;
-    static bss_begin: u8;
-    static bss_end: u8;
-    static boot_stack_begin: u8;
-    static boot_stack_end: u8;
-}