From 02c67051e8c4d3022261fd3bf7b9c695e9fc0e3a Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 4 Sep 2020 16:38:48 +0800 Subject: [PATCH] CPU options for better performance L2 cache options and prefetch options --- libcortex_a9/src/l2c.rs | 15 +++++++++++++++ libcortex_a9/src/regs.rs | 6 ++++++ libsupport_zynq/src/boot.rs | 2 ++ 3 files changed, 23 insertions(+) diff --git a/libcortex_a9/src/l2c.rs b/libcortex_a9/src/l2c.rs index 32ee460..b66d597 100644 --- a/libcortex_a9/src/l2c.rs +++ b/libcortex_a9/src/l2c.rs @@ -8,6 +8,13 @@ pub fn enable_l2_cache() { // disable L2 cache regs.reg1_control.modify(|_, w| w.l2_enable(false)); + regs.reg15_prefetch_ctrl.modify(|_, w| + w.instr_prefetch_en(true) + .data_prefetch_en(true) + .double_linefill_en(true) + .incr_double_linefill_en(true) + .pref_drop_en(true) + ); regs.reg1_aux_control.modify(|_, w| { w.early_bresp_en(true) .instr_prefetch_en(true) @@ -190,6 +197,8 @@ struct RegisterBlock { /// memory if the line is marked as valid and dirty. The lines are marked as not valid. /// Completes as a background task with the way, or ways, locked, preventing allocation. pub reg7_clean_inv_way: RW, + unused9: [u32; 0x1D8], + pub reg15_prefetch_ctrl: Reg15PrefetechCtrl, } register_at!(RegisterBlock, 0xF8F02000, new); @@ -311,3 +320,9 @@ register_bits!(reg7_clean_inv_index, way, u8, 28, 30); register_bits!(reg7_clean_inv_index, index, u8, 5, 11); register_bit!(reg7_clean_inv_index, c, 0); +register!(reg15_prefetch_ctrl, Reg15PrefetechCtrl, RW, u32); +register_bit!(reg15_prefetch_ctrl, double_linefill_en, 30); +register_bit!(reg15_prefetch_ctrl, instr_prefetch_en, 29); +register_bit!(reg15_prefetch_ctrl, data_prefetch_en, 28); +register_bit!(reg15_prefetch_ctrl, pref_drop_en, 24); +register_bit!(reg15_prefetch_ctrl, incr_double_linefill_en, 23); diff --git a/libcortex_a9/src/regs.rs b/libcortex_a9/src/regs.rs index f49d89f..398da6d 100644 --- a/libcortex_a9/src/regs.rs +++ b/libcortex_a9/src/regs.rs @@ -156,6 +156,8 @@ register_bit!(actlr, excl, 7); register_bit!(actlr, smp, 6); register_bit!(actlr, write_full_line_of_zeros, 3); register_bit!(actlr, l1_prefetch_enable, 2); +// L2 cache prefetch hint, in UG585 section 3.4.8 +register_bit!(actlr, l2_prefetch_enable, 1); // Cache/TLB maintenance broadcast register_bit!(actlr, fw, 0); @@ -173,6 +175,10 @@ impl ACTLR { pub fn enable_smp(&mut self) { self.modify(|_, w| w.smp(true).fw(true)); } + + pub fn enable_prefetch(&mut self) { + self.modify(|_, w| w.l1_prefetch_enable(true).l2_prefetch_enable(true)) + } } /// Domain Access Control Register diff --git a/libsupport_zynq/src/boot.rs b/libsupport_zynq/src/boot.rs index 56e6700..54315ac 100644 --- a/libsupport_zynq/src/boot.rs +++ b/libsupport_zynq/src/boot.rs @@ -53,6 +53,7 @@ unsafe fn boot_core0() -> ! { mmu::with_mmu(mmu_table, || { mpcore.scu_control.start(); ACTLR.enable_smp(); + ACTLR.enable_prefetch(); // TODO: Barriers reqd when core1 is not yet starting? asm::dmb(); asm::dsb(); @@ -74,6 +75,7 @@ unsafe fn boot_core1() -> ! { let mmu_table = mmu::L1Table::get(); mmu::with_mmu(mmu_table, || { ACTLR.enable_smp(); + ACTLR.enable_prefetch(); // TODO: Barriers reqd when core1 is not yet starting? asm::dmb(); asm::dsb();