Skip to content

Commit 3ee9ca5

Browse files
authored
Merge pull request #1828 from hermit-os/phys_virt_mem
refactor(mm): remove physicalmem/virtualmem freestanding functions
2 parents 9804a49 + faa1692 commit 3ee9ca5

File tree

21 files changed

+313
-344
lines changed

21 files changed

+313
-344
lines changed

src/arch/aarch64/kernel/interrupts.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ use aarch64::regs::*;
88
use ahash::RandomState;
99
use arm_gic::gicv3::{GicV3, InterruptGroup, SgiTarget, SgiTargetGroup};
1010
use arm_gic::{IntId, Trigger};
11+
use free_list::PageLayout;
1112
use hashbrown::HashMap;
1213
use hermit_dtb::Dtb;
1314
use hermit_sync::{InterruptSpinMutex, InterruptTicketMutex, OnceCell, SpinMutex};
15+
use memory_addresses::VirtAddr;
1416
use memory_addresses::arch::aarch64::PhysAddr;
1517

1618
use crate::arch::aarch64::kernel::core_local::increment_irq_counter;
@@ -21,7 +23,7 @@ use crate::drivers::mmio::get_interrupt_handlers;
2123
#[cfg(feature = "pci")]
2224
use crate::drivers::pci::get_interrupt_handlers;
2325
use crate::drivers::{InterruptHandlerQueue, InterruptLine};
24-
use crate::mm::virtualmem;
26+
use crate::mm::virtualmem::KERNEL_FREE_LIST;
2527
use crate::scheduler::{self, CoreId};
2628
use crate::{core_id, core_scheduler, env};
2729

@@ -310,8 +312,9 @@ pub(crate) fn init() {
310312
"Found generic interrupt controller redistributor at {gicr_start:p} (size {gicr_size:#X})"
311313
);
312314

313-
let gicd_address =
314-
virtualmem::allocate_aligned(gicd_size.try_into().unwrap(), 0x10000).unwrap();
315+
let layout = PageLayout::from_size_align(gicd_size.try_into().unwrap(), 0x10000).unwrap();
316+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
317+
let gicd_address = VirtAddr::from(page_range.start());
315318
debug!("Mapping GIC Distributor interface to virtual address {gicd_address:p}",);
316319

317320
let mut flags = PageTableEntryFlags::empty();
@@ -323,8 +326,9 @@ pub(crate) fn init() {
323326
flags,
324327
);
325328

326-
let gicr_address =
327-
virtualmem::allocate_aligned(gicr_size.try_into().unwrap(), 0x10000).unwrap();
329+
let layout = PageLayout::from_size_align(gicr_size.try_into().unwrap(), 0x10000).unwrap();
330+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
331+
let gicr_address = VirtAddr::from(page_range.start());
328332
debug!("Mapping generic interrupt controller to virtual address {gicr_address:p}",);
329333
paging::map::<BasePageSize>(
330334
gicr_address,

src/arch/aarch64/kernel/pci.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use core::str;
33

44
use arm_gic::{IntId, Trigger};
55
use bit_field::BitField;
6+
use free_list::PageLayout;
67
use hermit_dtb::Dtb;
78
use memory_addresses::arch::aarch64::{PhysAddr, VirtAddr};
89
use pci_types::{
@@ -13,7 +14,7 @@ use pci_types::{
1314
use crate::arch::aarch64::kernel::interrupts::GIC;
1415
use crate::arch::aarch64::mm::paging::{self, BasePageSize, PageSize, PageTableEntryFlags};
1516
use crate::drivers::pci::{PCI_DEVICES, PciDevice};
16-
use crate::mm::virtualmem;
17+
use crate::mm::virtualmem::KERNEL_FREE_LIST;
1718
use crate::{core_id, env};
1819

1920
const PCI_MAX_DEVICE_NUMBER: u8 = 32;
@@ -244,8 +245,10 @@ pub fn init() {
244245
let (slice, _residual_slice) = residual_slice.split_at(core::mem::size_of::<u64>());
245246
let size = u64::from_be_bytes(slice.try_into().unwrap());
246247

247-
let pci_address =
248-
virtualmem::allocate_aligned(size.try_into().unwrap(), 0x1000_0000).unwrap();
248+
let layout =
249+
PageLayout::from_size_align(size.try_into().unwrap(), 0x1000_0000).unwrap();
250+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
251+
let pci_address = VirtAddr::from(page_range.start());
249252
info!(
250253
"Mapping PCI Enhanced Configuration Space interface to virtual address {pci_address:p} (size {size:#X})"
251254
);

src/arch/aarch64/kernel/scheduler.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ use core::sync::atomic::Ordering;
1111
use core::{mem, ptr};
1212

1313
use align_address::Align;
14+
use free_list::{PageLayout, PageRange};
1415
use memory_addresses::arch::aarch64::{PhysAddr, VirtAddr};
1516

1617
use crate::arch::aarch64::kernel::CURRENT_STACK_ADDRESS;
1718
use crate::arch::aarch64::kernel::core_local::core_scheduler;
1819
use crate::arch::aarch64::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
1920
#[cfg(not(feature = "common-os"))]
2021
use crate::env;
22+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
23+
use crate::mm::virtualmem::KERNEL_FREE_LIST;
2124
#[cfg(target_os = "none")]
2225
use crate::scheduler::PerCoreSchedulerExt;
2326
use crate::scheduler::task::{Task, TaskFrame};
@@ -132,11 +135,15 @@ impl TaskStacks {
132135
size.align_up(BasePageSize::SIZE as usize)
133136
};
134137
let total_size = user_stack_size + DEFAULT_STACK_SIZE;
135-
let virt_addr =
136-
crate::mm::virtualmem::allocate(total_size + 3 * BasePageSize::SIZE as usize)
137-
.expect("Failed to allocate Virtual Memory for TaskStacks");
138-
let phys_addr = crate::mm::physicalmem::allocate(total_size)
138+
let layout = PageLayout::from_size(total_size + 3 * BasePageSize::SIZE as usize).unwrap();
139+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
140+
let virt_addr = VirtAddr::from(page_range.start());
141+
let frame_layout = PageLayout::from_size(total_size).unwrap();
142+
let frame_range = PHYSICAL_FREE_LIST
143+
.lock()
144+
.allocate(frame_layout)
139145
.expect("Failed to allocate Physical Memory for TaskStacks");
146+
let phys_addr = PhysAddr::from(frame_range.start());
140147

141148
debug!(
142149
"Create stacks at {:p} with a size of {} KB",
@@ -233,11 +240,21 @@ impl Drop for TaskStacks {
233240
stacks.virt_addr,
234241
stacks.total_size / BasePageSize::SIZE as usize + 3,
235242
);
236-
crate::mm::virtualmem::deallocate(
237-
stacks.virt_addr,
243+
let range = PageRange::from_start_len(
244+
stacks.virt_addr.as_usize(),
238245
stacks.total_size + 3 * BasePageSize::SIZE as usize,
239-
);
240-
crate::mm::physicalmem::deallocate(stacks.phys_addr, stacks.total_size);
246+
)
247+
.unwrap();
248+
unsafe {
249+
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
250+
}
251+
252+
let range =
253+
PageRange::from_start_len(stacks.phys_addr.as_usize(), stacks.total_size)
254+
.unwrap();
255+
unsafe {
256+
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
257+
}
241258
}
242259
}
243260
}

src/arch/aarch64/kernel/systemtime.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use alloc::vec::Vec;
44
use core::arch::asm;
55
use core::str;
66

7+
use free_list::PageLayout;
78
use hermit_dtb::Dtb;
89
use hermit_entry::boot_info::PlatformInfo;
910
use hermit_sync::OnceCell;
@@ -13,6 +14,7 @@ use time::OffsetDateTime;
1314
use crate::arch::aarch64::mm::paging::{self, BasePageSize, PageSize, PageTableEntryFlags};
1415
use crate::env;
1516
use crate::mm::virtualmem;
17+
use crate::mm::virtualmem::KERNEL_FREE_LIST;
1618

1719
static PL031_ADDRESS: OnceCell<VirtAddr> = OnceCell::new();
1820
static BOOT_TIME: OnceCell<u64> = OnceCell::new();
@@ -78,11 +80,9 @@ pub fn init() {
7880

7981
debug!("Found RTC at {addr:p} (size {size:#X})");
8082

81-
let pl031_address = virtualmem::allocate_aligned(
82-
size.try_into().unwrap(),
83-
BasePageSize::SIZE.try_into().unwrap(),
84-
)
85-
.unwrap();
83+
let layout = PageLayout::from_size(size.try_into().unwrap()).unwrap();
84+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
85+
let pl031_address = VirtAddr::from(page_range.start());
8686
PL031_ADDRESS.set(pl031_address).unwrap();
8787
debug!("Mapping RTC to virtual address {pl031_address:p}",);
8888

src/arch/aarch64/mm/paging.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ use core::marker::PhantomData;
55
use core::{fmt, mem, ptr};
66

77
use align_address::Align;
8+
use free_list::PageLayout;
89
use memory_addresses::{PhysAddr, VirtAddr};
910

1011
use crate::arch::aarch64::kernel::{get_base_address, get_image_size, get_ram_address, processor};
1112
use crate::env::is_uhyve;
1213
use crate::mm::physicalmem;
14+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
1315
use crate::{KERNEL_STACK_SIZE, mm, scheduler};
1416

1517
/// Pointer to the root page table (called "Level 0" in ARM terminology).
@@ -494,8 +496,12 @@ where
494496
// Does the table exist yet?
495497
if !self.entries[index].is_present() {
496498
// Allocate a single 4 KiB page for the new entry and mark it as a valid, writable subtable.
497-
let physical_address = physicalmem::allocate(BasePageSize::SIZE as usize)
499+
let frame_layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
500+
let frame_range = PHYSICAL_FREE_LIST
501+
.lock()
502+
.allocate(frame_layout)
498503
.expect("Unable to allocate physical memory");
504+
let physical_address = PhysAddr::from(frame_range.start());
499505
self.entries[index].set(
500506
physical_address,
501507
PageTableEntryFlags::NORMAL | PageTableEntryFlags::TABLE_OR_4KIB_PAGE,
@@ -662,7 +668,11 @@ pub fn map_heap<S: PageSize>(virt_addr: VirtAddr, nr_pages: usize) -> Result<(),
662668
while map_counter < nr_pages {
663669
let size = (nr_pages - map_counter) * S::SIZE as usize;
664670
for i in (S::SIZE as usize..=size).rev().step_by(S::SIZE as usize) {
665-
if let Ok(phys_addr) = physicalmem::allocate_aligned(i, S::SIZE as usize) {
671+
let layout = PageLayout::from_size_align(i, S::SIZE as usize).unwrap();
672+
let frame_range = PHYSICAL_FREE_LIST.lock().allocate(layout);
673+
674+
if let Ok(frame_range) = frame_range {
675+
let phys_addr = PhysAddr::from(frame_range.start());
666676
map::<S>(
667677
virt_addr + map_counter * S::SIZE as usize,
668678
phys_addr,

src/arch/riscv64/kernel/devicetree.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,20 @@ pub fn init_drivers() {
244244
// Verify the device-ID to find the network card
245245
let id = mmio.as_ptr().device_id().read();
246246

247-
// crate::mm::physicalmem::reserve(
248-
// PhysAddr::from(current_address.align_down(BasePageSize::SIZE as usize)),
249-
// BasePageSize::SIZE as usize,
250-
// );
247+
if cfg!(debug_assertions) {
248+
use free_list::PageRange;
249+
250+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
251+
252+
let start = virtio_region.starting_address.addr();
253+
let len = virtio_region.size.unwrap();
254+
let frame_range = PageRange::from_start_len(start, len).unwrap();
255+
256+
PHYSICAL_FREE_LIST
257+
.lock()
258+
.allocate_at(frame_range)
259+
.unwrap_err();
260+
}
251261

252262
match id {
253263
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "gem-net")))]

src/arch/riscv64/kernel/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ pub mod serial;
1414
mod start;
1515
pub mod switch;
1616
pub mod systemtime;
17-
1817
use alloc::vec::Vec;
1918
use core::ptr;
2019
use core::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering};
2120

2221
use fdt::Fdt;
22+
use free_list::PageLayout;
2323
use memory_addresses::{PhysAddr, VirtAddr};
2424
use riscv::register::sstatus;
2525

@@ -29,7 +29,7 @@ use crate::arch::riscv64::kernel::processor::lsb;
2929
use crate::config::KERNEL_STACK_SIZE;
3030
use crate::env;
3131
use crate::init_cell::InitCell;
32-
use crate::mm::physicalmem;
32+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
3333

3434
// Used to store information about available harts. The index of the hart in the vector
3535
// represents its CpuId and does not need to match its hart_id
@@ -161,8 +161,12 @@ pub fn boot_next_processor() {
161161
if let Some(next_hart_id) = next_hart_index {
162162
{
163163
debug!("Allocating stack for hard_id {next_hart_id}");
164-
let stack = physicalmem::allocate(KERNEL_STACK_SIZE)
164+
let frame_layout = PageLayout::from_size(KERNEL_STACK_SIZE).unwrap();
165+
let frame_range = PHYSICAL_FREE_LIST
166+
.lock()
167+
.allocate(frame_layout)
165168
.expect("Failed to allocate boot stack for new core");
169+
let stack = PhysAddr::from(frame_range.start());
166170
CURRENT_STACK_ADDRESS.store(stack.as_usize() as _, Ordering::Relaxed);
167171
}
168172

src/arch/riscv64/kernel/scheduler.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ use core::convert::TryInto;
77
use core::{mem, ptr};
88

99
use align_address::Align;
10+
use free_list::{PageLayout, PageRange};
1011
use memory_addresses::{PhysAddr, VirtAddr};
1112

1213
use crate::arch::riscv64::kernel::core_local::core_scheduler;
1314
use crate::arch::riscv64::kernel::processor::set_oneshot_timer;
1415
use crate::arch::riscv64::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
1516
#[cfg(not(feature = "common-os"))]
1617
use crate::env;
18+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
19+
use crate::mm::virtualmem::KERNEL_FREE_LIST;
1720
use crate::scheduler::task::{Task, TaskFrame};
1821
use crate::{DEFAULT_STACK_SIZE, KERNEL_STACK_SIZE};
1922

@@ -116,12 +119,15 @@ impl TaskStacks {
116119
size.align_up(BasePageSize::SIZE as usize)
117120
};
118121
let total_size = user_stack_size + DEFAULT_STACK_SIZE + KERNEL_STACK_SIZE;
119-
let virt_addr =
120-
crate::mm::virtualmem::allocate(total_size + 4 * BasePageSize::SIZE as usize)
121-
//let virt_addr = crate::arch::mm::virtualmem::allocate(total_size)
122-
.expect("Failed to allocate Virtual Memory for TaskStacks");
123-
let phys_addr = crate::mm::physicalmem::allocate(total_size)
122+
let layout = PageLayout::from_size(total_size + 4 * BasePageSize::SIZE as usize).unwrap();
123+
let page_range = KERNEL_FREE_LIST.lock().allocate(layout).unwrap();
124+
let virt_addr = VirtAddr::from(page_range.start());
125+
let frame_layout = PageLayout::from_size(total_size).unwrap();
126+
let frame_range = PHYSICAL_FREE_LIST
127+
.lock()
128+
.allocate(frame_layout)
124129
.expect("Failed to allocate Physical Memory for TaskStacks");
130+
let phys_addr = PhysAddr::from(frame_range.start());
125131

126132
debug!(
127133
"Create stacks at {:#X} with a size of {} KB",
@@ -251,12 +257,21 @@ impl Drop for TaskStacks {
251257
stacks.total_size / BasePageSize::SIZE as usize + 4,
252258
//stacks.total_size / BasePageSize::SIZE as usize,
253259
);
254-
crate::mm::virtualmem::deallocate(
255-
stacks.virt_addr,
260+
let range = PageRange::from_start_len(
261+
stacks.virt_addr.as_usize(),
256262
stacks.total_size + 4 * BasePageSize::SIZE as usize,
257-
//stacks.total_size,
258-
);
259-
crate::mm::physicalmem::deallocate(stacks.phys_addr, stacks.total_size);
263+
)
264+
.unwrap();
265+
unsafe {
266+
KERNEL_FREE_LIST.lock().deallocate(range).unwrap();
267+
}
268+
269+
let range =
270+
PageRange::from_start_len(stacks.phys_addr.as_usize(), stacks.total_size)
271+
.unwrap();
272+
unsafe {
273+
PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap();
274+
}
260275
}
261276
}
262277
}

src/arch/riscv64/mm/paging.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ use core::marker::PhantomData;
22
use core::ptr;
33

44
use align_address::Align;
5+
use free_list::PageLayout;
56
use hermit_sync::SpinMutex;
67
use memory_addresses::{AddrRange, PhysAddr, VirtAddr};
78
use riscv::asm::sfence_vma;
89
use riscv::register::satp;
910
use riscv::register::satp::Satp;
1011

11-
use crate::mm::physicalmem;
12+
use crate::mm::physicalmem::PHYSICAL_FREE_LIST;
1213

1314
static ROOT_PAGETABLE: SpinMutex<PageTable<L2Table>> = SpinMutex::new(PageTable::new());
1415

@@ -433,7 +434,9 @@ where
433434
// Does the table exist yet?
434435
if !self.entries[index].is_present() {
435436
// Allocate a single 4 KiB page for the new entry and mark it as a valid, writable subtable.
436-
let new_entry = physicalmem::allocate(BasePageSize::SIZE as usize).unwrap();
437+
let frame_layout = PageLayout::from_size(BasePageSize::SIZE as usize).unwrap();
438+
let frame_range = PHYSICAL_FREE_LIST.lock().allocate(frame_layout).unwrap();
439+
let new_entry = PhysAddr::from(frame_range.start());
437440
self.entries[index].set(new_entry, PageTableEntryFlags::BLANK);
438441

439442
// trace!("new_entry {:#X}", new_entry);
@@ -610,8 +613,12 @@ pub fn map_heap<S: PageSize>(virt_addr: VirtAddr, count: usize) -> Result<(), us
610613
let virt_addrs = (0..count as u64).map(|n| virt_addr + n * S::SIZE);
611614

612615
for (map_counter, virt_addr) in virt_addrs.enumerate() {
613-
let phys_addr = physicalmem::allocate_aligned(S::SIZE as usize, S::SIZE as usize)
616+
let layout = PageLayout::from_size_align(S::SIZE as usize, S::SIZE as usize).unwrap();
617+
let frame_range = PHYSICAL_FREE_LIST
618+
.lock()
619+
.allocate(layout)
614620
.map_err(|_| map_counter)?;
621+
let phys_addr = PhysAddr::from(frame_range.start());
615622
map::<S>(virt_addr, phys_addr, 1, flags);
616623
}
617624

0 commit comments

Comments
 (0)