From 2ac85cd40fe08a422f460792677d29c7798fd54b Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 29 Oct 2016 21:34:25 +0000 Subject: [PATCH] runtime: implement prototype background RPCs. --- artiq/gateware/amp/kernel_cpu.py | 2 +- artiq/runtime.rs/Cargo.toml | 2 +- artiq/runtime.rs/libksupport/Cargo.lock | 22 +++++++ artiq/runtime.rs/libksupport/Cargo.toml | 4 ++ artiq/runtime.rs/libksupport/api.rs | 1 + artiq/runtime.rs/libksupport/dyld.rs | 1 - artiq/runtime.rs/libksupport/lib.rs | 58 ++++++++++++++++-- artiq/runtime.rs/libstd_artiq/lib.rs | 51 +--------------- artiq/runtime.rs/src/kernel_proto.rs | 6 +- artiq/runtime.rs/src/lib.rs | 54 +++++++++++++++- artiq/runtime.rs/src/{rpc.rs => rpc_proto.rs} | 14 +++-- artiq/runtime.rs/src/rpc_queue.rs | 61 +++++++++++++++++++ artiq/runtime.rs/src/session.rs | 41 +++++++++---- artiq/runtime.rs/src/session_proto.rs | 5 +- artiq/runtime/Makefile | 3 + artiq/runtime/ksupport.ld | 6 +- artiq/runtime/ksupport_glue.c | 4 +- artiq/runtime/runtime.ld | 4 +- 18 files changed, 252 insertions(+), 87 deletions(-) rename artiq/runtime.rs/src/{rpc.rs => rpc_proto.rs} (97%) create mode 100644 artiq/runtime.rs/src/rpc_queue.rs diff --git a/artiq/gateware/amp/kernel_cpu.py b/artiq/gateware/amp/kernel_cpu.py index 2736027e3..6aca00d32 100644 --- a/artiq/gateware/amp/kernel_cpu.py +++ b/artiq/gateware/amp/kernel_cpu.py @@ -7,7 +7,7 @@ from misoc.integration.soc_core import mem_decoder class KernelCPU(Module): def __init__(self, platform, - exec_address=0x40400000, + exec_address=0x40800000, main_mem_origin=0x40000000, l2_size=8192): self._reset = CSRStorage(reset=1) diff --git a/artiq/runtime.rs/Cargo.toml b/artiq/runtime.rs/Cargo.toml index 29d415a15..1355f7a4e 100644 --- a/artiq/runtime.rs/Cargo.toml +++ b/artiq/runtime.rs/Cargo.toml @@ -16,7 +16,7 @@ path = "src/lib.rs" std_artiq = { path = "libstd_artiq" } lwip = { path = "liblwip", default-features = false } fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } -log = { version = "0.3", default-features = false, features = ["max_level_debug"] } +log = { version = "0.3", default-features = false, features = [] } log_buffer = { version = "1.0" } byteorder = { version = "0.5", default-features = false } diff --git a/artiq/runtime.rs/libksupport/Cargo.lock b/artiq/runtime.rs/libksupport/Cargo.lock index da7d2b081..df5a6a1bb 100644 --- a/artiq/runtime.rs/libksupport/Cargo.lock +++ b/artiq/runtime.rs/libksupport/Cargo.lock @@ -1,4 +1,26 @@ [root] name = "ksupport" version = "0.0.0" +dependencies = [ + "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "std_artiq 0.0.0", +] +[[package]] +name = "alloc_artiq" +version = "0.0.0" + +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "std_artiq" +version = "0.0.0" +dependencies = [ + "alloc_artiq 0.0.0", +] + +[metadata] +"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" diff --git a/artiq/runtime.rs/libksupport/Cargo.toml b/artiq/runtime.rs/libksupport/Cargo.toml index e5a29ff08..9ba7d5f65 100644 --- a/artiq/runtime.rs/libksupport/Cargo.toml +++ b/artiq/runtime.rs/libksupport/Cargo.toml @@ -8,6 +8,10 @@ name = "ksupport" path = "lib.rs" crate-type = ["staticlib"] +[dependencies] +std_artiq = { path = "../libstd_artiq" } +byteorder = { version = "0.5", default-features = false } + [profile.dev] panic = 'unwind' opt-level = 2 diff --git a/artiq/runtime.rs/libksupport/api.rs b/artiq/runtime.rs/libksupport/api.rs index 46570feab..aa6483bbd 100644 --- a/artiq/runtime.rs/libksupport/api.rs +++ b/artiq/runtime.rs/libksupport/api.rs @@ -91,6 +91,7 @@ static mut API: &'static [(&'static str, *const ())] = &[ api!(watchdog_clear = ::watchdog_clear), api!(send_rpc = ::send_rpc), + api!(send_async_rpc = ::send_async_rpc), api!(recv_rpc = ::recv_rpc), api!(cache_get = ::cache_get), diff --git a/artiq/runtime.rs/libksupport/dyld.rs b/artiq/runtime.rs/libksupport/dyld.rs index c25f7daea..c73653a19 100644 --- a/artiq/runtime.rs/libksupport/dyld.rs +++ b/artiq/runtime.rs/libksupport/dyld.rs @@ -1,5 +1,4 @@ use core::{ptr, slice, str}; -use core::slice::SliceExt; use libc::{c_void, c_char, c_int, size_t}; #[allow(non_camel_case_types)] diff --git a/artiq/runtime.rs/libksupport/lib.rs b/artiq/runtime.rs/libksupport/lib.rs index 5b12c360e..53e62f4e5 100644 --- a/artiq/runtime.rs/libksupport/lib.rs +++ b/artiq/runtime.rs/libksupport/lib.rs @@ -1,25 +1,51 @@ -#![feature(lang_items, needs_panic_runtime, asm, libc, core_slice_ext)] +#![feature(lang_items, needs_panic_runtime, asm, libc, stmt_expr_attributes)] #![no_std] #![needs_panic_runtime] +#[macro_use] +extern crate std_artiq as std; extern crate libc; +extern crate byteorder; #[path = "../src/board.rs"] mod board; #[path = "../src/mailbox.rs"] mod mailbox; +#[path = "../src/rpc_queue.rs"] +mod rpc_queue; + +#[path = "../src/proto.rs"] +mod proto; #[path = "../src/kernel_proto.rs"] mod kernel_proto; +#[path = "../src/rpc_proto.rs"] +mod rpc_proto; mod dyld; mod api; use core::{mem, ptr, slice, str}; +use std::io::Cursor; use libc::{c_char, size_t}; use kernel_proto::*; use dyld::Library; +#[no_mangle] +pub extern "C" fn malloc(_size: usize) -> *mut libc::c_void { + unimplemented!() +} + +#[no_mangle] +pub extern "C" fn realloc(_ptr: *mut libc::c_void, _size: usize) -> *mut libc::c_void { + unimplemented!() +} + +#[no_mangle] +pub extern "C" fn free(_ptr: *mut libc::c_void) { + unimplemented!() +} + fn send(request: &Message) { unsafe { mailbox::send(request as *const _ as usize) } while !mailbox::acknowledged() {} @@ -81,13 +107,37 @@ extern fn send_rpc(service: u32, tag: *const u8, data: *const *const ()) { let tag = unsafe { slice::from_raw_parts(tag, strlen(tag as *const c_char)) }; send(&RpcSend { - service: service as u32, - batch: service == 0, + async: false, + service: service, tag: tag, data: data }) } +extern fn send_async_rpc(service: u32, tag: *const u8, data: *const *const ()) { + extern { fn strlen(s: *const c_char) -> size_t; } + let tag = unsafe { slice::from_raw_parts(tag, strlen(tag as *const c_char)) }; + + while rpc_queue::full() {} + rpc_queue::enqueue(|mut slice| { + let length = { + let mut writer = Cursor::new(&mut slice[4..]); + try!(rpc_proto::send_args(&mut writer, service, tag, data)); + writer.position() + }; + proto::write_u32(&mut slice, length as u32) + }).unwrap_or_else(|err| { + assert!(err.kind() == std::io::ErrorKind::UnexpectedEof); + + send(&RpcSend { + async: true, + service: service, + tag: tag, + data: data + }) + }) +} + extern fn recv_rpc(slot: *mut ()) -> usize { send(&RpcRecvRequest(slot)); recv!(&RpcRecvReply(ref result) => { @@ -206,7 +256,7 @@ unsafe fn attribute_writeback(typeinfo: *const ()) { attributes = attributes.offset(1); if !(*attribute).tag.is_null() { - send_rpc(0, (*attribute).tag, [ + send_async_rpc(0, (*attribute).tag, [ &object as *const _ as *const (), &(*attribute).name as *const _ as *const (), (object as usize + (*attribute).offset) as *const () diff --git a/artiq/runtime.rs/libstd_artiq/lib.rs b/artiq/runtime.rs/libstd_artiq/lib.rs index 568dc8663..dafffbc9f 100644 --- a/artiq/runtime.rs/libstd_artiq/lib.rs +++ b/artiq/runtime.rs/libstd_artiq/lib.rs @@ -8,7 +8,7 @@ extern crate rustc_unicode; extern crate alloc_artiq; extern crate alloc; #[macro_use] -#[macro_reexport(vec)] +#[macro_reexport(vec, format)] extern crate collections; extern crate libc; @@ -31,52 +31,3 @@ pub mod prelude { pub mod error; pub mod io; - -use core::fmt::Write; - -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*))); -} - -#[macro_export] -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} - -extern { - fn putchar(c: libc::c_int) -> libc::c_int; - fn readchar() -> libc::c_char; -} - -pub struct Console; - -impl core::fmt::Write for Console { - fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { - for c in s.bytes() { unsafe { putchar(c as i32); } } - Ok(()) - } -} - -pub fn print_fmt(args: self::core::fmt::Arguments) { - let _ = Console.write_fmt(args); -} - -#[lang = "panic_fmt"] -extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! { - let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args); - let _ = write!(Console, "waiting for debugger...\n"); - unsafe { - let _ = readchar(); - loop { asm!("l.trap 0") } - } -} - -// Allow linking with crates that are built as -Cpanic=unwind even when the root crate -// is built with -Cpanic=abort. -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn _Unwind_Resume() -> ! { - loop {} -} diff --git a/artiq/runtime.rs/src/kernel_proto.rs b/artiq/runtime.rs/src/kernel_proto.rs index a75875738..d98be19f8 100644 --- a/artiq/runtime.rs/src/kernel_proto.rs +++ b/artiq/runtime.rs/src/kernel_proto.rs @@ -3,8 +3,8 @@ use core::marker::PhantomData; use core::fmt; -pub const KERNELCPU_EXEC_ADDRESS: usize = 0x40400000; -pub const KERNELCPU_PAYLOAD_ADDRESS: usize = 0x40440000; +pub const KERNELCPU_EXEC_ADDRESS: usize = 0x40800080; +pub const KERNELCPU_PAYLOAD_ADDRESS: usize = 0x40840000; pub const KERNELCPU_LAST_ADDRESS: usize = 0x4fffffff; pub const KSUPPORT_HEADER_SIZE: usize = 0x80; @@ -42,8 +42,8 @@ pub enum Message<'a> { WatchdogClear { id: usize }, RpcSend { + async: bool, service: u32, - batch: bool, tag: &'a [u8], data: *const *const () }, diff --git a/artiq/runtime.rs/src/lib.rs b/artiq/runtime.rs/src/lib.rs index 278b738e6..e661c427f 100644 --- a/artiq/runtime.rs/src/lib.rs +++ b/artiq/runtime.rs/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] -#![feature(libc, const_fn, try_borrow, stmt_expr_attributes, repr_simd, asm)] +#![feature(libc, const_fn, try_borrow, stmt_expr_attributes, repr_simd, asm, + lang_items)] #[macro_use] extern crate std_artiq as std; @@ -11,13 +12,54 @@ extern crate byteorder; extern crate fringe; extern crate lwip; +use core::fmt::Write; use logger::BufferLogger; +extern { + fn putchar(c: libc::c_int) -> libc::c_int; + fn readchar() -> libc::c_char; +} + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +} + +pub struct Console; + +impl core::fmt::Write for Console { + fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { + for c in s.bytes() { unsafe { putchar(c as i32); } } + Ok(()) + } +} + +pub fn print_fmt(args: self::core::fmt::Arguments) { + let _ = Console.write_fmt(args); +} + +#[lang = "panic_fmt"] +extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! { + let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args); + let _ = write!(Console, "waiting for debugger...\n"); + unsafe { + let _ = readchar(); + loop { asm!("l.trap 0") } + } +} + mod board; mod config; mod clock; mod rtio_crg; mod mailbox; +mod rpc_queue; mod urc; mod sched; @@ -29,9 +71,9 @@ mod kernel_proto; mod session_proto; mod moninj_proto; mod analyzer_proto; +mod rpc_proto; mod kernel; -mod rpc; mod session; mod moninj; #[cfg(has_rtio_analyzer)] @@ -44,6 +86,14 @@ extern { include!(concat!(env!("OUT_DIR"), "/git_info.rs")); +// Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort. +// This is never called. +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn _Unwind_Resume() -> ! { + loop {} +} + #[no_mangle] pub unsafe extern fn rust_main() { static mut LOG_BUFFER: [u8; 4096] = [0; 4096]; diff --git a/artiq/runtime.rs/src/rpc.rs b/artiq/runtime.rs/src/rpc_proto.rs similarity index 97% rename from artiq/runtime.rs/src/rpc.rs rename to artiq/runtime.rs/src/rpc_proto.rs index 21b966dc9..d302d389d 100644 --- a/artiq/runtime.rs/src/rpc.rs +++ b/artiq/runtime.rs/src/rpc_proto.rs @@ -1,5 +1,7 @@ -use std::slice; -use std::io::{self, Read, Write, BufWriter}; +#![allow(dead_code)] + +use core::slice; +use std::io::{self, Read, Write}; use proto::*; use self::tag::{Tag, TagIterator, split_tag}; @@ -74,6 +76,7 @@ unsafe fn recv_value(reader: &mut Read, tag: Tag, data: &mut *mut (), pub fn recv_return(reader: &mut Read, tag_bytes: &[u8], data: *mut (), alloc: &Fn(usize) -> io::Result<*mut ()>) -> io::Result<()> { let mut it = TagIterator::new(tag_bytes); + #[cfg(not(ksupport))] trace!("recv ...->{}", it); let tag = it.next().expect("truncated tag"); @@ -98,7 +101,6 @@ unsafe fn send_value(writer: &mut Write, tag: Tag, data: &mut *const ()) -> io:: }) } - let writer = &mut BufWriter::new(writer); try!(write_u8(writer, tag.as_u8())); match tag { Tag::None => Ok(()), @@ -161,14 +163,16 @@ unsafe fn send_value(writer: &mut Write, tag: Tag, data: &mut *const ()) -> io:: } } -pub fn send_args(writer: &mut Write, tag_bytes: &[u8], +pub fn send_args(writer: &mut Write, service: u32, tag_bytes: &[u8], data: *const *const ()) -> io::Result<()> { let (arg_tags_bytes, return_tag_bytes) = split_tag(tag_bytes); let mut args_it = TagIterator::new(arg_tags_bytes); let return_it = TagIterator::new(return_tag_bytes); - trace!("send ({})->{}", args_it, return_it); + #[cfg(not(ksupport))] + trace!("send<{}>({})->{}", service, args_it, return_it); + try!(write_u32(writer, service)); for index in 0.. { if let Some(arg_tag) = args_it.next() { let mut data = unsafe { *data.offset(index) }; diff --git a/artiq/runtime.rs/src/rpc_queue.rs b/artiq/runtime.rs/src/rpc_queue.rs new file mode 100644 index 000000000..f0f89f144 --- /dev/null +++ b/artiq/runtime.rs/src/rpc_queue.rs @@ -0,0 +1,61 @@ +#![allow(dead_code)] + +use core::ptr::{read_volatile, write_volatile}; +use core::slice; +use board; + +const SEND_MAILBOX: *mut usize = (board::mem::MAILBOX_BASE + 4) as *mut usize; +const RECV_MAILBOX: *mut usize = (board::mem::MAILBOX_BASE + 8) as *mut usize; + +const QUEUE_BEGIN: usize = 0x40400000; +const QUEUE_END: usize = 0x40800000; +const QUEUE_CHUNK: usize = 0x1000; + +pub unsafe fn init() { + write_volatile(SEND_MAILBOX, QUEUE_BEGIN); + write_volatile(RECV_MAILBOX, QUEUE_END); +} + +fn next(mut addr: usize) -> usize { + debug_assert!(addr % QUEUE_CHUNK == 0); + debug_assert!(addr >= QUEUE_BEGIN && addr < QUEUE_END); + + addr += QUEUE_CHUNK; + if addr == QUEUE_END { addr = QUEUE_BEGIN } + addr +} + +pub fn empty() -> bool { + unsafe { read_volatile(SEND_MAILBOX) == read_volatile(RECV_MAILBOX) } +} + +pub fn full() -> bool { + unsafe { next(read_volatile(SEND_MAILBOX)) == read_volatile(RECV_MAILBOX) } +} + +pub fn enqueue(f: F) -> Result + where F: FnOnce(&mut [u8]) -> Result { + debug_assert!(!full()); + + unsafe { + let slice = slice::from_raw_parts_mut(read_volatile(SEND_MAILBOX) as *mut u8, QUEUE_CHUNK); + f(slice).and_then(|x| { + write_volatile(SEND_MAILBOX, next(read_volatile(SEND_MAILBOX))); + Ok(x) + }) + } +} + +pub fn dequeue(f: F) -> Result + where F: FnOnce(&mut [u8]) -> Result { + debug_assert!(!empty()); + + unsafe { + board::flush_cpu_dcache(); + let slice = slice::from_raw_parts_mut(read_volatile(RECV_MAILBOX) as *mut u8, QUEUE_CHUNK); + f(slice).and_then(|x| { + write_volatile(RECV_MAILBOX, next(read_volatile(RECV_MAILBOX))); + Ok(x) + }) + } +} diff --git a/artiq/runtime.rs/src/session.rs b/artiq/runtime.rs/src/session.rs index 0c05f4a5c..dacb14d67 100644 --- a/artiq/runtime.rs/src/session.rs +++ b/artiq/runtime.rs/src/session.rs @@ -1,16 +1,16 @@ use std::prelude::v1::*; use std::{mem, str}; use std::cell::RefCell; -use std::fmt::Write; -use std::io::{self, Read}; -use {config, rtio_crg, clock, mailbox, kernel}; +use std::io::{self, Read, Write, BufWriter}; +use {config, rtio_crg, clock, mailbox, rpc_queue, kernel}; use logger::BufferLogger; use cache::Cache; use urc::Urc; use sched::{ThreadHandle, Waiter, Spawner}; use sched::{TcpListener, TcpStream, SocketAddr, IP_ANY}; +use byteorder::{ByteOrder, NetworkEndian}; -use rpc; +use rpc_proto as rpc; use session_proto as host; use kernel_proto as kern; @@ -132,7 +132,8 @@ fn kern_recv_notrace(waiter: Waiter, f: F) -> io::Result where F: FnOnce(&kern::Message) -> io::Result { try!(waiter.until(|| mailbox::receive() != 0)); if !kernel::validate(mailbox::receive()) { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid kernel CPU pointer")) + let message = format!("invalid kernel CPU pointer 0x{:x}", mailbox::receive()); + return Err(io::Error::new(io::ErrorKind::InvalidData, message)) } f(unsafe { mem::transmute::(mailbox::receive()) }) @@ -352,6 +353,7 @@ fn process_kern_message(waiter: Waiter, kern_recv_dotrace(request); match request { &kern::Log(args) => { + use std::fmt::Write; try!(session.log_buffer.write_fmt(args) .map_err(|_| io_error("cannot append to session log buffer"))); session.flush_log_buffer(); @@ -383,15 +385,13 @@ fn process_kern_message(waiter: Waiter, kern_acknowledge() } - &kern::RpcSend { service, batch, tag, data } => { + &kern::RpcSend { async, service, tag, data } => { match stream { None => unexpected!("unexpected RPC in flash kernel"), Some(ref mut stream) => { - try!(host_write(stream, host::Reply::RpcRequest { - service: service - })); - try!(rpc::send_args(stream, tag, data)); - if !batch { + try!(host_write(stream, host::Reply::RpcRequest)); + try!(rpc::send_args(&mut BufWriter::new(stream), service, tag, data)); + if !async { session.kernel_state = KernelState::RpcWait } kern_acknowledge() @@ -465,12 +465,27 @@ fn process_kern_message(waiter: Waiter, }) } +fn process_kern_queued_rpc(stream: &mut TcpStream, + session: &mut Session) -> io::Result<()> { + rpc_queue::dequeue(|slice| { + trace!("comm<-kern (async RPC)"); + let length = NetworkEndian::read_u32(slice) as usize; + try!(host_write(stream, host::Reply::RpcRequest)); + try!(stream.write(&slice[4..][..length])); + Ok(()) + }) +} + fn host_kernel_worker(waiter: Waiter, stream: &mut TcpStream, congress: &mut Congress) -> io::Result<()> { let mut session = Session::new(congress); loop { + if !rpc_queue::empty() { + try!(process_kern_queued_rpc(stream, &mut session)) + } + if stream.readable() { try!(process_host_message(waiter, stream, &mut session)); } @@ -509,6 +524,10 @@ fn flash_kernel_worker(waiter: Waiter, try!(kern_run(&mut session)); loop { + if !rpc_queue::empty() { + return Err(io_error("unexpected background RPC in flash kernel")) + } + if mailbox::receive() != 0 { if try!(process_kern_message(waiter, None, &mut session)) { return Ok(()) diff --git a/artiq/runtime.rs/src/session_proto.rs b/artiq/runtime.rs/src/session_proto.rs index 7babdc35a..2ee656c35 100644 --- a/artiq/runtime.rs/src/session_proto.rs +++ b/artiq/runtime.rs/src/session_proto.rs @@ -107,7 +107,7 @@ pub enum Reply<'a> { backtrace: &'a [usize] }, - RpcRequest { service: u32 }, + RpcRequest, FlashRead(&'a [u8]), FlashOk, @@ -170,9 +170,8 @@ impl<'a> Reply<'a> { } }, - Reply::RpcRequest { service } => { + Reply::RpcRequest => { try!(write_u8(writer, 10)); - try!(write_u32(writer, service)); }, Reply::FlashRead(ref bytes) => { diff --git a/artiq/runtime/Makefile b/artiq/runtime/Makefile index c543b7d66..e8936fdf4 100644 --- a/artiq/runtime/Makefile +++ b/artiq/runtime/Makefile @@ -7,6 +7,8 @@ OBJECTS := flash_storage.o main.o OBJECTS_KSUPPORT := ksupport_glue.o artiq_personality.o rtio.o dds.o i2c.o RUSTOUT_DIRECTORY := cargo/or1k-unknown-none/debug +CORE_IO_COMMIT := d40c593f42fafbac1ff3d827f6df96338b5b7d8b +export CORE_IO_COMMIT CFLAGS += \ -I$(LIBALLOC_DIRECTORY) \ @@ -54,6 +56,7 @@ $(RUSTOUT_DIRECTORY)/libksupport.a: --manifest-path $(realpath $(RUNTIME_DIRECTORY)/../runtime.rs/libksupport/Cargo.toml) \ --target=or1k-unknown-none -- \ $(shell cat $(BUILDINC_DIRECTORY)/generated/rust-cfg) \ + --cfg ksupport \ -C target-feature=+mul,+div,+ffl1,+cmov,+addc -C opt-level=s \ -L../libcompiler-rt diff --git a/artiq/runtime/ksupport.ld b/artiq/runtime/ksupport.ld index de2267304..1e0ed5040 100644 --- a/artiq/runtime/ksupport.ld +++ b/artiq/runtime/ksupport.ld @@ -6,10 +6,14 @@ INCLUDE generated/regions.ld /* First 4M of main memory are reserved for runtime * code/data/heap, then comes kernel memory. + * Next 4M of main memory are reserved for + * the background RPC queue. * First 256K of kernel memory are for support code. + * Support code is loaded at ORIGIN-0x80 so that ELF headers + * are also loaded. */ MEMORY { - ksupport (RWX) : ORIGIN = 0x40400000, LENGTH = 0x40000 + ksupport (RWX) : ORIGIN = 0x40800080, LENGTH = 0x40000 } /* Kernel stack is at the end of main RAM. */ diff --git a/artiq/runtime/ksupport_glue.c b/artiq/runtime/ksupport_glue.c index 9de97b75d..2fa056f5e 100644 --- a/artiq/runtime/ksupport_glue.c +++ b/artiq/runtime/ksupport_glue.c @@ -8,8 +8,8 @@ void send_to_log(const char *ptr, size_t length); -#define KERNELCPU_EXEC_ADDRESS 0x40400000 -#define KERNELCPU_PAYLOAD_ADDRESS 0x40440000 +#define KERNELCPU_EXEC_ADDRESS 0x40800080 +#define KERNELCPU_PAYLOAD_ADDRESS 0x40840000 #define KERNELCPU_LAST_ADDRESS 0x4fffffff #define KSUPPORT_HEADER_SIZE 0x80 diff --git a/artiq/runtime/runtime.ld b/artiq/runtime/runtime.ld index 5d3d00e08..42e7e2cd2 100644 --- a/artiq/runtime/runtime.ld +++ b/artiq/runtime/runtime.ld @@ -74,9 +74,7 @@ SECTIONS .heap : { _fheap = .; - . = ORIGIN(runtime) + LENGTH(runtime) - /* Leave room for ksupport headers. */ - - 0x1000; + . = ORIGIN(runtime) + LENGTH(runtime); _eheap = .; } > runtime