mmu: align l1_table

smoltcp
Astro 2019-06-18 02:22:07 +02:00
parent 9bebfb49bc
commit 1634513bc7
3 changed files with 45 additions and 30 deletions

4
link.x
View File

@ -40,8 +40,10 @@ SECTIONS
*(.data) *(.data)
} > OCM } > OCM
.bss ALIGN(0x1000) (NOLOAD) : .bss ALIGN(0x4000) (NOLOAD) :
{ {
/* Aligned to 16 kB */
KEEP(*(.bss.l1_table));
*(.bss) *(.bss)
} > OCM } > OCM
__bss_start = ADDR(.bss); __bss_start = ADDR(.bss);

View File

@ -94,20 +94,31 @@ impl L1Entry {
} }
} }
const L1TABLE_SIZE: usize = 4096; const L1_TABLE_SIZE: usize = 4096;
#[doc(hidden)]
#[link_section = ".bss.l1_table"]
#[no_mangle]
pub static mut l1_table: L1Table = L1Table {
table: [L1Entry(0); L1_TABLE_SIZE]
};
#[repr(C, align(16384))] /// The `#[repr(align(16384))]` is unfortunately ineffective. Hence we
/// require explicit linking to a region defined in the linker script.
#[repr(align(16384))]
pub struct L1Table { pub struct L1Table {
table: [L1Entry; L1TABLE_SIZE] table: [L1Entry; L1_TABLE_SIZE]
} }
impl L1Table { impl L1Table {
pub fn flat_layout() -> Self { pub fn get() -> &'static mut Self {
let mut result = L1Table { unsafe {
table: unsafe { uninitialized() } &mut l1_table
}; }
}
pub fn setup_flat_layout(&mut self) -> &Self {
/* 0x00000000 - 0x00100000 (cacheable) */ /* 0x00000000 - 0x00100000 (cacheable) */
result.direct_mapped_section(0, L1Section { self.direct_mapped_section(0, L1Section {
global: true, global: true,
shareable: true, shareable: true,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -119,7 +130,7 @@ impl L1Table {
}); });
/* (DDR cacheable) */ /* (DDR cacheable) */
for ddr in 1..=0x1ff { for ddr in 1..=0x1ff {
result.direct_mapped_section(ddr, L1Section { self.direct_mapped_section(ddr, L1Section {
global: true, global: true,
shareable: true, shareable: true,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -132,7 +143,7 @@ impl L1Table {
} }
/* (unassigned/reserved). */ /* (unassigned/reserved). */
for undef in 0x1ff..=0x3ff { for undef in 0x1ff..=0x3ff {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -145,7 +156,7 @@ impl L1Table {
} }
/* 0x40000000 - 0x7fffffff (FPGA slave0) */ /* 0x40000000 - 0x7fffffff (FPGA slave0) */
for fpga_slave in 0x400..=0x7ff { for fpga_slave in 0x400..=0x7ff {
result.direct_mapped_section(fpga_slave, L1Section { self.direct_mapped_section(fpga_slave, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -158,7 +169,7 @@ impl L1Table {
} }
/* 0x80000000 - 0xbfffffff (FPGA slave1) */ /* 0x80000000 - 0xbfffffff (FPGA slave1) */
for fpga_slave in 0x800..=0xbff { for fpga_slave in 0x800..=0xbff {
result.direct_mapped_section(fpga_slave, L1Section { self.direct_mapped_section(fpga_slave, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -171,7 +182,7 @@ impl L1Table {
} }
/* 0xc0000000 - 0xdfffffff (unassigned/reserved). */ /* 0xc0000000 - 0xdfffffff (unassigned/reserved). */
for undef in 0xc00..=0xdff { for undef in 0xc00..=0xdff {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -185,7 +196,7 @@ impl L1Table {
/* 0xe0000000 - 0xe02fffff (Memory mapped devices) /* 0xe0000000 - 0xe02fffff (Memory mapped devices)
* UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */ * UART/USB/IIC/SPI/CAN/GEM/GPIO/QSPI/SD/NAND */
for mmapped_dev in 0xe00..=0xe02 { for mmapped_dev in 0xe00..=0xe02 {
result.direct_mapped_section(mmapped_dev, L1Section { self.direct_mapped_section(mmapped_dev, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -198,7 +209,7 @@ impl L1Table {
} }
/* 0xe0300000 - 0xe0ffffff (unassigned/reserved). */ /* 0xe0300000 - 0xe0ffffff (unassigned/reserved). */
for undef in 0xe03..=0xe0f { for undef in 0xe03..=0xe0f {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -211,7 +222,7 @@ impl L1Table {
} }
/* 0xe1000000 - 0xe1ffffff (NAND) */ /* 0xe1000000 - 0xe1ffffff (NAND) */
for nand in 0xe10..=0xe1f { for nand in 0xe10..=0xe1f {
result.direct_mapped_section(nand, L1Section { self.direct_mapped_section(nand, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -224,7 +235,7 @@ impl L1Table {
} }
/* 0xe2000000 - 0xe3ffffff (NOR) */ /* 0xe2000000 - 0xe3ffffff (NOR) */
for nor in 0xe20..=0xe3f { for nor in 0xe20..=0xe3f {
result.direct_mapped_section(nor, L1Section { self.direct_mapped_section(nor, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -237,7 +248,7 @@ impl L1Table {
} }
/* 0xe4000000 - 0xe5ffffff (SRAM) */ /* 0xe4000000 - 0xe5ffffff (SRAM) */
for nor in 0xe40..=0xe5f { for nor in 0xe40..=0xe5f {
result.direct_mapped_section(nor, L1Section { self.direct_mapped_section(nor, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -250,7 +261,7 @@ impl L1Table {
} }
/* 0xe6000000 - 0xf7ffffff (unassigned/reserved). */ /* 0xe6000000 - 0xf7ffffff (unassigned/reserved). */
for undef in 0xe60..=0xf7f { for undef in 0xe60..=0xf7f {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -263,7 +274,7 @@ impl L1Table {
} }
/* 0xf8000000 - 0xf8ffffff (AMBA APB Peripherals) */ /* 0xf8000000 - 0xf8ffffff (AMBA APB Peripherals) */
for apb in 0xf80..=0xf8f { for apb in 0xf80..=0xf8f {
result.direct_mapped_section(apb, L1Section { self.direct_mapped_section(apb, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -276,7 +287,7 @@ impl L1Table {
} }
/* 0xf9000000 - 0xfbffffff (unassigned/reserved). */ /* 0xf9000000 - 0xfbffffff (unassigned/reserved). */
for undef in 0xf90..=0xfbf { for undef in 0xf90..=0xfbf {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -289,7 +300,7 @@ impl L1Table {
} }
/* 0xfc000000 - 0xfdffffff (Linear QSPI - XIP) */ /* 0xfc000000 - 0xfdffffff (Linear QSPI - XIP) */
for qspi in 0xfc0..=0xfdf { for qspi in 0xfc0..=0xfdf {
result.direct_mapped_section(qspi, L1Section { self.direct_mapped_section(qspi, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -302,7 +313,7 @@ impl L1Table {
} }
/* 0xfe000000 - 0xffefffff (unassigned/reserved). */ /* 0xfe000000 - 0xffefffff (unassigned/reserved). */
for undef in 0xfe0..=0xffe { for undef in 0xfe0..=0xffe {
result.direct_mapped_section(undef, L1Section { self.direct_mapped_section(undef, L1Section {
global: false, global: false,
shareable: false, shareable: false,
access: AccessPermissions::PermissionFault, access: AccessPermissions::PermissionFault,
@ -314,7 +325,7 @@ impl L1Table {
}); });
} }
/* 0xfff00000 - 0xffffffff (256K OCM when mapped to high address space) */ /* 0xfff00000 - 0xffffffff (256K OCM when mapped to high address space) */
result.direct_mapped_section(0xfff, L1Section { self.direct_mapped_section(0xfff, L1Section {
global: true, global: true,
shareable: false, shareable: false,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
@ -325,12 +336,12 @@ impl L1Table {
bufferable: true, bufferable: true,
}); });
result self
} }
#[inline(always)] #[inline(always)]
fn direct_mapped_section(&mut self, index: usize, section: L1Section) { fn direct_mapped_section(&mut self, index: usize, section: L1Section) {
assert!(index < L1TABLE_SIZE); assert!(index < L1_TABLE_SIZE);
let base = (index as u32) << 20; let base = (index as u32) << 20;
self.table[index] = L1Entry::section(base, section); self.table[index] = L1Entry::section(base, section);
@ -353,7 +364,7 @@ pub fn with_mmu<F: FnMut() -> !>(l1table: &L1Table, mut f: F) -> ! {
.irgn0(true) .irgn0(true)
.table_base(table_base >> 14) .table_base(table_base >> 14)
); );
// Enable I-Cache and D-Cache // Enable I-Cache and D-Cache
SCTLR.write( SCTLR.write(
SCTLR::zeroed() SCTLR::zeroed()

View File

@ -52,7 +52,9 @@ unsafe fn boot_core0() -> ! {
l1_cache_init(); l1_cache_init();
zero_bss(&mut __bss_start, &mut __bss_end); zero_bss(&mut __bss_start, &mut __bss_end);
mmu::with_mmu(&mmu::L1Table::flat_layout(), || { let mmu_table = mmu::L1Table::get()
.setup_flat_layout();
mmu::with_mmu(mmu_table, || {
main(); main();
panic!("return from main"); panic!("return from main");
}); });
@ -99,7 +101,7 @@ fn main() {
match eth.recv_next() { match eth.recv_next() {
None => {} None => {}
Some(pkt) => { Some(pkt) => {
writeln!(uart, "eth: received {} bytes", pkt.len()); writeln!(uart, "eth: received {} bytes\r", pkt.len());
} }
} }
} }