kernel: use smaller pages for rtio/dma/batch

This commit is contained in:
2026-02-20 11:57:49 +08:00
committed by sb10q
parent d39785a4f8
commit 268c702aa3
5 changed files with 59 additions and 26 deletions

View File

@@ -5,13 +5,13 @@ MEMORY
/* TEXT is also a part of SDRAM. However linker won't match
VMA and LDA after we do some overlaying with the code,
so we just create a new region. */
TEXT : ORIGIN = 0x00100000, LENGTH = 0x400000
SDRAM : ORIGIN = 0x00500000, LENGTH = 0x1FB00000
TEXT : ORIGIN = 0x00100000, LENGTH = 0x100000
SDRAM : ORIGIN = 0x00200000, LENGTH = 0x1FB00000
}
SECTIONS
{
PAGE_SIZE = 1M;
PAGE_SIZE = 4K;
__text_start = .;
.text :
{
@@ -23,31 +23,40 @@ SECTIONS
} > TEXT
. = ALIGN(PAGE_SIZE);
__rtio_page = .;
__rtio_page = .;
__rtio_page_wide = . + PAGE_SIZE / 2;
.rtio_page __rtio_page : AT(__rtio_page)
{
*(rtio_output);
. = __rtio_page + PAGE_SIZE / 2;
} > TEXT
.rtio_wide_page __rtio_page_wide : AT(__rtio_page_wide)
{
*(rtio_output_wide);
} > TEXT
__dma_page = __rtio_page + PAGE_SIZE;
.dma_page __rtio_page : AT(__dma_page)
__dma_page_wide = __dma_page + PAGE_SIZE / 2;
.dma_page __rtio_page : AT(__dma_page)
{
*(dma_record_output);
. = __rtio_page + PAGE_SIZE / 2;
} > TEXT
.dma_wide_page __rtio_page_wide : AT(__dma_page_wide)
{
*(dma_record_output_wide);
} > TEXT
__batch_page = __dma_page + PAGE_SIZE;
.batch_page __rtio_page : AT(__batch_page)
__batch_page_wide = __batch_page + PAGE_SIZE / 2;
.batch_page __rtio_page : AT(__batch_page)
{
*(batch_output);
. = __rtio_page + PAGE_SIZE / 2;
} > TEXT
.batch_wide_page __rtio_page_wide : AT(__batch_page_wide)
{
*(batch_output_wide);
} > TEXT
/* End of TEXT region, start of SDRAM region, necessary for linker not to move things around */
__text_end = ORIGIN(SDRAM);
__exidx_start = ORIGIN(SDRAM);
@@ -62,17 +71,17 @@ SECTIONS
{
* (.ARM.extab*)
} > SDRAM
.rodata : ALIGN(4)
{
*(.rodata .rodata.*);
} > SDRAM
.data : ALIGN(4)
{
*(.data .data.*);
} > SDRAM
.bss (NOLOAD) : ALIGN(4)
{
__bss_start = .;

View File

@@ -8,6 +8,7 @@ use dyld::{Library, elf::EXIDX_Entry};
use libboard_zynq::{gic, mpcore};
use libcortex_a9::{asm::{dsb, isb},
cache::{bpiall, dcci_slice, iciallu},
mmu::{link_l2_page_table, L2Table},
sync_channel};
use libsupport_zynq::ram;
use log::{debug, error, info};
@@ -28,6 +29,29 @@ extern "C" {
pub static __batch_page: u32;
}
pub static mut L2_TEXT_TABLE: L2Table = L2Table::new();
fn prepare_l2_page_table() {
unsafe {
let rtio_page = &__rtio_page as *const _ as u32;
let dma_page = &__dma_page as *const _ as u32;
#[cfg(ki_impl = "acp")]
let batch_page = &__batch_page as *const _ as u32;
// for simplicity we want to have all the rtio, dma and batch
// pages in the same 1MB block, otherwise we need two L2 tables
assert!(rtio_page & !0x000f_ffff == dma_page & !0x000f_ffff);
#[cfg(ki_impl = "acp")]
assert!(rtio_page & !0x000f_ffff == batch_page & !0x000f_ffff);
let main_base = rtio_page & !0x000f_ffff;
// set up the table
// potentially todo: setup large sections for rtio/dma/batch
// but only if 4k proves to be not enough
L2_TEXT_TABLE.setup_flat_layout(main_base);
link_l2_page_table(main_base, &L2_TEXT_TABLE);
}
}
unsafe fn attribute_writeback(typeinfo: *const ()) {
#[repr(C)]
struct Attr {
@@ -153,6 +177,8 @@ pub extern "C" fn main_core1() {
*CHANNEL_1TO0.lock() = Some(core0_rx);
CHANNEL_SEM.signal();
prepare_l2_page_table();
// set on load, cleared on start
let mut loaded_kernel = None;
loop {

View File

@@ -2,10 +2,9 @@ use alloc::{string::String, vec::Vec};
use core::{mem, ptr};
use cslice::CSlice;
use libcortex_a9::mmu;
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message,
core1::{__dma_page, __rtio_page},
core1::{__dma_page, __rtio_page, L2_TEXT_TABLE},
rtio};
use crate::{artiq_raise, pl::csr};
@@ -45,7 +44,7 @@ pub extern "C" fn dma_record_start(name: CSlice<u8>) {
artiq_raise!("DMAError", "DMA is already recording")
}
mmu::remap_section(&__rtio_page as *const _ as u32, &__dma_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__dma_page as *const _ as u32);
RECORDER = Some(DmaRecorder {
name,
@@ -62,7 +61,7 @@ pub extern "C" fn dma_record_stop(duration: i64, enable_ddma: bool) {
artiq_raise!("DMAError", "DMA is not recording")
}
mmu::remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
let mut recorder = RECORDER.take().unwrap();
recorder.duration = duration;
recorder.enable_ddma = enable_ddma;

View File

@@ -1,10 +1,10 @@
use core::sync::atomic::{Ordering, fence};
use cslice::CSlice;
use libcortex_a9::{asm, mmu};
use libcortex_a9::asm;
use vcell::VolatileCell;
use super::core1::{__batch_page, __rtio_page};
use super::core1::{__batch_page, __rtio_page, L2_TEXT_TABLE};
#[cfg(has_drtio)]
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message};
use crate::{artiq_raise, pl::csr, rtio_core};
@@ -90,7 +90,7 @@ pub extern "C" fn init() {
csr::rtio::in_base_write(&IN_BUFFER as *const InTransaction as u32);
csr::rtio::out_base_write(&OUT_BUFFER as *const OutBuffer as u32);
csr::rtio::enable_write(1);
mmu::remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
OUT_BUFFER.running = BATCH_DISABLED;
}
#[cfg(has_drtio)]
@@ -310,7 +310,7 @@ pub extern "C" fn batch_start() {
if OUT_BUFFER.running == BATCH_ENABLED {
artiq_raise!("RuntimeError", "Batched mode is already running.");
}
mmu::remap_section(&__rtio_page as *const _ as u32, &__batch_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__batch_page as *const _ as u32);
OUT_BUFFER.running = BATCH_ENABLED;
OUT_BUFFER.ptr = 0;
}
@@ -320,7 +320,7 @@ pub extern "C" fn batch_end() {
unsafe {
if OUT_BUFFER.ptr == 0 {
OUT_BUFFER.running = BATCH_DISABLED;
mmu::remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
return;
}
// dmb and send event (commit the event to gateware)
@@ -329,7 +329,7 @@ pub extern "C" fn batch_end() {
// start cleaning up before reading status
OUT_BUFFER.running = BATCH_DISABLED;
mmu::remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
let status = loop {
let status = IN_BUFFER.reply_status.get();
if status != 0 {

View File

@@ -1,11 +1,10 @@
use core::ptr::{read_volatile, write_volatile};
use cslice::CSlice;
use libcortex_a9::mmu;
#[cfg(has_drtio)]
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message};
use crate::{artiq_raise, kernel::core1::__rtio_page, pl::csr, rtio_core};
use crate::{artiq_raise, kernel::core1::{__rtio_page, L2_TEXT_TABLE}, pl::csr, rtio_core};
pub const RTIO_O_STATUS_WAIT: u8 = 1;
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
@@ -24,7 +23,7 @@ pub struct TimestampedData {
pub extern "C" fn init() {
unsafe {
rtio_core::reset_write(1);
mmu::remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
L2_TEXT_TABLE.remap_section(&__rtio_page as *const _ as u32, &__rtio_page as *const _ as u32);
}
#[cfg(has_drtio)]
unsafe {