@@ -16,6 +16,8 @@ use buddy_slab_allocator::{AllocResult, PageAllocator};
1616use kspin:: SpinNoIrq ;
1717use strum:: { IntoStaticStr , VariantArray } ;
1818
19+ pub use buddy_slab_allocator:: AddrTranslator ;
20+
1921// Page size can be configured from here
2022const PAGE_SIZE : usize = 0x1000 ;
2123
@@ -78,7 +80,7 @@ impl fmt::Debug for Usages {
7880/// This is an adapter around the allocator::GlobalAllocator that provides
7981/// compatibility with the original axalloc API.
8082pub struct GlobalAllocator {
81- inner : buddy_slab_allocator:: GlobalAllocator < PAGE_SIZE > ,
83+ inner : SpinNoIrq < buddy_slab_allocator:: GlobalAllocator < PAGE_SIZE > > ,
8284 usages : SpinNoIrq < Usages > ,
8385}
8486
@@ -92,40 +94,50 @@ impl GlobalAllocator {
9294 /// Creates an empty [`GlobalAllocator`].
9395 pub const fn new ( ) -> Self {
9496 Self {
95- inner : buddy_slab_allocator:: GlobalAllocator :: < PAGE_SIZE > :: new ( ) ,
97+ inner : SpinNoIrq :: new ( buddy_slab_allocator:: GlobalAllocator :: < PAGE_SIZE > :: new ( ) ) ,
9698 usages : SpinNoIrq :: new ( Usages :: new ( ) ) ,
9799 }
98100 }
99101
102+ /// Configure the address translator used by the underlying allocator so
103+ /// that it can reason about physical address ranges (e.g. low-memory
104+ /// regions below 4GiB).
105+ pub fn set_addr_translator (
106+ & self ,
107+ translator : & ' static dyn buddy_slab_allocator:: AddrTranslator ,
108+ ) {
109+ self . inner . lock ( ) . set_addr_translator ( translator) ;
110+ }
111+
100112 /// Returns the name of the allocator.
101113 pub const fn name ( & self ) -> & ' static str {
102- "buddy_slab_allocator "
114+ "buddy-slab-allocator "
103115 }
104116
105117 /// Initializes the allocator with the given region.
106118 pub fn init ( & self , start_vaddr : usize , size : usize ) {
107119 info ! (
108- "Initialize global memory allocator, addr:[{:#x}-{:#x}) " ,
109- start_vaddr, start_vaddr + size
120+ "Initialize global memory allocator, start_vaddr: {}, size: {} " ,
121+ start_vaddr, size
110122 ) ;
111- if let Err ( e) = self . inner . init ( start_vaddr, size) {
123+ if let Err ( e) = self . inner . lock ( ) . init ( start_vaddr, size) {
112124 panic ! ( "Failed to initialize allocator: {:?}" , e) ;
113125 }
114126 }
115127
116128 /// Add the given region to the allocator.
117129 pub fn add_memory ( & self , start_vaddr : usize , size : usize ) -> AllocResult {
118- info ! (
119- "Add memory region to allocator, addr:[{:#x}-{:#x}) " ,
120- start_vaddr, start_vaddr + size
130+ info ! (
131+ "Add memory region, start_vaddr: {}, size: {} " ,
132+ start_vaddr, size
121133 ) ;
122- self . inner . add_memory ( start_vaddr, size)
134+ self . inner . lock ( ) . add_memory ( start_vaddr, size)
123135 }
124136
125137 /// Allocate arbitrary number of bytes. Returns the left bound of the
126138 /// allocated region.
127139 pub fn alloc ( & self , layout : Layout ) -> AllocResult < NonNull < u8 > > {
128- let result = self . inner . alloc ( layout) ;
140+ let result = self . inner . lock ( ) . alloc ( layout) ;
129141 if let Ok ( _ptr) = result {
130142 self . usages . lock ( ) . alloc ( UsageKind :: RustHeap , layout. size ( ) ) ;
131143 }
@@ -137,7 +149,7 @@ impl GlobalAllocator {
137149 self . usages
138150 . lock ( )
139151 . dealloc ( UsageKind :: RustHeap , layout. size ( ) ) ;
140- self . inner . dealloc ( pos, layout) ;
152+ self . inner . lock ( ) . dealloc ( pos, layout) ;
141153 }
142154
143155 /// Allocates contiguous pages.
@@ -147,7 +159,22 @@ impl GlobalAllocator {
147159 alignment : usize ,
148160 kind : UsageKind ,
149161 ) -> AllocResult < usize > {
150- let result = self . inner . alloc_pages ( num_pages, alignment) ;
162+ let result = self . inner . lock ( ) . alloc_pages ( num_pages, alignment) ;
163+ if let Ok ( _addr) = result {
164+ let size = num_pages * PAGE_SIZE ;
165+ self . usages . lock ( ) . alloc ( kind, size) ;
166+ }
167+ result
168+ }
169+
170+ /// Allocates contiguous low-memory pages (physical address < 4GiB).
171+ pub fn alloc_dma32_pages (
172+ & self ,
173+ num_pages : usize ,
174+ alignment : usize ,
175+ kind : UsageKind ,
176+ ) -> AllocResult < usize > {
177+ let result = self . inner . lock ( ) . alloc_dma32_pages ( num_pages, alignment) ;
151178 if let Ok ( _addr) = result {
152179 let size = num_pages * PAGE_SIZE ;
153180 self . usages . lock ( ) . alloc ( kind, size) ;
@@ -157,13 +184,16 @@ impl GlobalAllocator {
157184
158185 /// Allocates contiguous pages starting from the given address.
159186 pub fn alloc_pages_at (
160- & mut self ,
187+ & self ,
161188 start : usize ,
162189 num_pages : usize ,
163190 alignment : usize ,
164191 kind : UsageKind ,
165192 ) -> AllocResult < usize > {
166- let result = self . inner . alloc_pages_at ( start, num_pages, alignment) ;
193+ let result = self
194+ . inner
195+ . lock ( )
196+ . alloc_pages_at ( start, num_pages, alignment) ;
167197 if let Ok ( _addr) = result {
168198 let size = num_pages * PAGE_SIZE ;
169199 self . usages . lock ( ) . alloc ( kind, size) ;
@@ -175,35 +205,35 @@ impl GlobalAllocator {
175205 pub fn dealloc_pages ( & self , pos : usize , num_pages : usize , kind : UsageKind ) {
176206 let size = num_pages * PAGE_SIZE ;
177207 self . usages . lock ( ) . dealloc ( kind, size) ;
178- self . inner . dealloc_pages ( pos, num_pages) ;
208+ self . inner . lock ( ) . dealloc_pages ( pos, num_pages) ;
179209 }
180210
181211 /// Returns the number of allocated bytes in the byte allocator.
182212 #[ cfg( feature = "tracking" ) ]
183213 pub fn used_bytes ( & self ) -> usize {
184- let stats = self . inner . get_stats ( ) ;
214+ let stats = self . inner . lock ( ) . get_stats ( ) ;
185215 stats. heap_bytes + stats. slab_bytes
186216 }
187217
188218 /// Returns the number of available bytes in the byte allocator.
189219 #[ cfg( feature = "tracking" ) ]
190220 pub fn available_bytes ( & self ) -> usize {
191221 // The new allocator doesn't have this exact method, so we approximate
192- let stats = self . inner . get_stats ( ) ;
222+ let stats = self . inner . lock ( ) . get_stats ( ) ;
193223 stats. free_pages * PAGE_SIZE
194224 }
195225
196226 /// Returns the number of allocated pages in the page allocator.
197227 #[ cfg( feature = "tracking" ) ]
198228 pub fn used_pages ( & self ) -> usize {
199- let stats = self . inner . get_stats ( ) ;
229+ let stats = self . inner . lock ( ) . get_stats ( ) ;
200230 stats. used_pages
201231 }
202232
203233 /// Returns the number of available pages in the page allocator.
204234 #[ cfg( feature = "tracking" ) ]
205235 pub fn available_pages ( & self ) -> usize {
206- let stats = self . inner . get_stats ( ) ;
236+ let stats = self . inner . lock ( ) . get_stats ( ) ;
207237 stats. free_pages
208238 }
209239
@@ -312,8 +342,30 @@ pub fn global_init(start_vaddr: usize, size: usize) {
312342 info ! ( "global allocator initialized" ) ;
313343}
314344
345+ struct FnAddrTranslator {
346+ func : fn ( memory_addr:: VirtAddr ) -> memory_addr:: PhysAddr ,
347+ }
348+
349+ impl buddy_slab_allocator:: AddrTranslator for FnAddrTranslator {
350+ fn virt_to_phys ( & self , va : usize ) -> Option < usize > {
351+ Some ( ( self . func ) ( memory_addr:: VirtAddr :: from ( va) ) . as_usize ( ) )
352+ }
353+ }
354+
355+ static mut GLOBAL_ADDR_TRANSLATOR : FnAddrTranslator = FnAddrTranslator {
356+ func : |_| memory_addr:: PhysAddr :: from ( 0usize ) ,
357+ } ;
358+
359+ pub fn configure_addr_translator ( func : fn ( memory_addr:: VirtAddr ) -> memory_addr:: PhysAddr ) {
360+ unsafe {
361+ GLOBAL_ADDR_TRANSLATOR . func = func;
362+ let translator: & ' static FnAddrTranslator = & * ( & raw const GLOBAL_ADDR_TRANSLATOR ) ;
363+ GLOBAL_ALLOCATOR . set_addr_translator ( translator) ;
364+ }
365+ }
366+
315367/// Add the given memory region to the global allocator.
316- ///
368+
317369/// Users should ensure that the region is valid and not being used by others,
318370/// so that the allocated memory is also valid.
319371///
0 commit comments