@@ -265,7 +265,7 @@ make chainbot
265
265
diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/aarch64/mmu.rs
266
266
--- 10_privilege_level/src/arch/aarch64/mmu.rs
267
267
+++ 11_virtual_memory/src/arch/aarch64/mmu.rs
268
- @@ -0,0 +1,316 @@
268
+ @@ -0,0 +1,300 @@
269
269
+ // SPDX-License-Identifier: MIT
270
270
+ //
271
271
+ // Copyright (c) 2018-2019 Andre Richter <[email protected] >
@@ -347,28 +347,32 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
347
347
+ ]
348
348
+ }
349
349
+
350
- + // Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into
351
- + // a PageDescriptor slot in `struct PageTables`, and vice versa.
350
+ + const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
351
+ + const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
352
+ +
353
+ + /// A table descriptor for 64 KiB aperture.
354
+ + ///
355
+ + /// The output points to the next table.
352
356
+ #[derive(Copy, Clone)]
353
357
+ #[repr(transparent)]
354
- + struct RawTableDescriptor (u64);
358
+ + struct TableDescriptor (u64);
355
359
+
360
+ + /// A page descriptor with 64 KiB aperture.
361
+ + ///
362
+ + /// The output points to physical memory.
356
363
+ #[derive(Copy, Clone)]
357
364
+ #[repr(transparent)]
358
- + struct RawPageDescriptor(u64);
359
- +
360
- + const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
361
- + const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
365
+ + struct PageDescriptor(u64);
362
366
+
363
367
+ /// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned,
364
368
+ /// hence the "reverse" order of appearance.
365
369
+ #[repr(C)]
366
370
+ #[repr(align(65536))]
367
371
+ struct PageTables<const N: usize> {
368
372
+ // Page descriptors, covering 64 KiB windows per entry.
369
- + lvl3: [[RawPageDescriptor ; 8192]; N],
373
+ + lvl3: [[PageDescriptor ; 8192]; N],
370
374
+ // Table descriptors, covering 512 MiB windows.
371
- + lvl2: [RawTableDescriptor ; N],
375
+ + lvl2: [TableDescriptor ; N],
372
376
+ }
373
377
+
374
378
+ /// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4.
@@ -378,8 +382,8 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
378
382
+ ///
379
383
+ /// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries.
380
384
+ static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables {
381
- + lvl3: [[RawPageDescriptor (0); 8192]; ENTRIES_512_MIB],
382
- + lvl2: [RawTableDescriptor (0); ENTRIES_512_MIB],
385
+ + lvl3: [[PageDescriptor (0); 8192]; ENTRIES_512_MIB],
386
+ + lvl2: [TableDescriptor (0); ENTRIES_512_MIB],
383
387
+ };
384
388
+
385
389
+ trait BaseAddr {
@@ -397,24 +401,15 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
397
401
+ }
398
402
+ }
399
403
+
400
- + /// A descriptor pointing to the next page table.
401
- + struct TableDescriptor(register::FieldValue<u64, STAGE1_TABLE_DESCRIPTOR::Register>);
402
- +
403
- + impl TableDescriptor {
404
- + fn new(next_lvl_table_addr: usize) -> TableDescriptor {
404
+ + impl convert::From<usize> for TableDescriptor {
405
+ + fn from(next_lvl_table_addr: usize) -> Self {
405
406
+ let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT;
407
+ + let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True
408
+ + + STAGE1_TABLE_DESCRIPTOR::TYPE::Table
409
+ + + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64))
410
+ + .value;
406
411
+
407
- + TableDescriptor(
408
- + STAGE1_TABLE_DESCRIPTOR::VALID::True
409
- + + STAGE1_TABLE_DESCRIPTOR::TYPE::Table
410
- + + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64),
411
- + )
412
- + }
413
- + }
414
- +
415
- + impl convert::From<TableDescriptor> for RawTableDescriptor {
416
- + fn from(desc: TableDescriptor) -> Self {
417
- + RawTableDescriptor(desc.0.value)
412
+ + TableDescriptor(val)
418
413
+ }
419
414
+ }
420
415
+
@@ -452,28 +447,17 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
452
447
+ }
453
448
+ }
454
449
+
455
- + /// A page descriptor with 64 KiB aperture.
456
- + ///
457
- + /// The output points to physical memory.
458
- + struct PageDescriptor(register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>);
459
- +
460
450
+ impl PageDescriptor {
461
451
+ fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor {
462
452
+ let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT;
463
- +
464
- + PageDescriptor(
465
- + STAGE1_PAGE_DESCRIPTOR::VALID::True
466
- + + STAGE1_PAGE_DESCRIPTOR::AF::True
467
- + + attribute_fields.into()
468
- + + STAGE1_PAGE_DESCRIPTOR::TYPE::Table
469
- + + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64),
470
- + )
471
- + }
472
- + }
473
- +
474
- + impl convert::From<PageDescriptor> for RawPageDescriptor {
475
- + fn from(desc: PageDescriptor) -> Self {
476
- + RawPageDescriptor(desc.0.value)
453
+ + let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True
454
+ + + STAGE1_PAGE_DESCRIPTOR::AF::True
455
+ + + attribute_fields.into()
456
+ + + STAGE1_PAGE_DESCRIPTOR::TYPE::Table
457
+ + + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64))
458
+ + .value;
459
+ +
460
+ + PageDescriptor(val)
477
461
+ }
478
462
+ }
479
463
+
@@ -505,15 +489,15 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
505
489
+ /// - Modifies a `static mut`. Ensure it only happens from here.
506
490
+ unsafe fn populate_pt_entries() -> Result<(), &'static str> {
507
491
+ for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() {
508
- + *l2_entry = TableDescriptor::new( TABLES.lvl3[l2_nr].base_addr_usize() ).into();
492
+ + *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into();
509
493
+
510
494
+ for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() {
511
495
+ let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT);
512
496
+
513
497
+ let (output_addr, attribute_fields) =
514
498
+ bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?;
515
499
+
516
- + *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into() ;
500
+ + *l3_entry = PageDescriptor::new(output_addr, attribute_fields);
517
501
+ }
518
502
+ }
519
503
+
0 commit comments