2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-18 16:06:30 +08:00

Merge branch 'rust'

This commit is contained in:
whitequark 2016-08-17 11:49:55 +00:00
commit 58efaad5c6
15 changed files with 255 additions and 17 deletions

View File

@ -171,7 +171,7 @@ class Target:
as results: as results:
library = results["output"].read() library = results["output"].read()
_dump(os.getenv("ARTIQ_DUMP_ELF"), "Shared library", ".so", _dump(os.getenv("ARTIQ_DUMP_ELF"), "Shared library", ".elf",
lambda: library) lambda: library)
return library return library

View File

@ -47,9 +47,9 @@ class StubEmbeddingMap:
class FileRunner(EnvExperiment): class FileRunner(EnvExperiment):
def build(self): def build(self, file):
self.setattr_device("core") self.setattr_device("core")
self.setattr_argument("file") self.file = file
self.target = OR1KTarget() self.target = OR1KTarget()
def run(self): def run(self):
@ -58,7 +58,8 @@ class FileRunner(EnvExperiment):
self.core.comm.load(kernel_library) self.core.comm.load(kernel_library)
self.core.comm.run() self.core.comm.run()
self.core.comm.serve(StubEmbeddingMap(), self.core.comm.serve(StubEmbeddingMap(),
lambda addresses: self.target.symbolize(kernel_library, addresses)) lambda addresses: self.target.symbolize(kernel_library, addresses), \
lambda symbols: self.target.demangle(symbols))
class ELFRunner(FileRunner): class ELFRunner(FileRunner):
@ -142,6 +143,9 @@ def get_argparser(with_file=True):
def _build_experiment(device_mgr, dataset_mgr, args): def _build_experiment(device_mgr, dataset_mgr, args):
arguments = parse_arguments(args.arguments)
argument_mgr = ProcessArgumentManager(arguments)
managers = (device_mgr, dataset_mgr, argument_mgr)
if hasattr(args, "file"): if hasattr(args, "file"):
is_elf = args.file.endswith(".elf") is_elf = args.file.endswith(".elf")
is_ll = args.file.endswith(".ll") is_ll = args.file.endswith(".ll")
@ -153,11 +157,11 @@ def _build_experiment(device_mgr, dataset_mgr, args):
raise ValueError("experiment-by-name not supported " raise ValueError("experiment-by-name not supported "
"for precompiled kernels") "for precompiled kernels")
if is_elf: if is_elf:
return ELFRunner(device_mgr, dataset_mgr, file=args.file) return ELFRunner(managers, file=args.file)
elif is_ll: elif is_ll:
return LLVMIRRunner(device_mgr, dataset_mgr, file=args.file) return LLVMIRRunner(managers, file=args.file)
elif is_bc: elif is_bc:
return LLVMBitcodeRunner(device_mgr, dataset_mgr, file=args.file) return LLVMBitcodeRunner(managers, file=args.file)
else: else:
import_cache.install_hook() import_cache.install_hook()
module = file_import(args.file, prefix="artiq_run_") module = file_import(args.file, prefix="artiq_run_")
@ -165,16 +169,13 @@ def _build_experiment(device_mgr, dataset_mgr, args):
else: else:
module = sys.modules["__main__"] module = sys.modules["__main__"]
file = getattr(module, "__file__") file = getattr(module, "__file__")
exp = get_experiment(module, args.experiment)
arguments = parse_arguments(args.arguments)
expid = { expid = {
"file": file, "file": file,
"experiment": args.experiment, "experiment": args.experiment,
"arguments": arguments "arguments": arguments
} }
device_mgr.virtual_devices["scheduler"].expid = expid device_mgr.virtual_devices["scheduler"].expid = expid
argument_mgr = ProcessArgumentManager(arguments) return get_experiment(module, args.experiment)(managers)
return exp((device_mgr, dataset_mgr, argument_mgr))
def run(with_file=False): def run(with_file=False):

18
artiq/runtime.rs/Cargo.lock generated Normal file
View File

@ -0,0 +1,18 @@
[root]
name = "runtime"
version = "0.0.0"
dependencies = [
"std_artiq 0.0.0",
]
[[package]]
name = "alloc_artiq"
version = "0.0.0"
[[package]]
name = "std_artiq"
version = "0.0.0"
dependencies = [
"alloc_artiq 0.0.0",
]

View File

@ -0,0 +1,16 @@
[package]
authors = ["The ARTIQ Project Developers"]
name = "runtime"
version = "0.0.0"
[lib]
name = "artiq_rust"
crate-type = ["staticlib"]
path = "src/lib.rs"
[dependencies]
std_artiq = { path = "libstd_artiq" }
[profile.dev]
panic = 'abort'
opt-level = 2

View File

@ -0,0 +1,8 @@
[package]
authors = ["The ARTIQ Project Developers"]
name = "alloc_artiq"
version = "0.0.0"
[lib]
name = "alloc_artiq"
path = "lib.rs"

View File

@ -0,0 +1,86 @@
#![feature(allocator, libc)]
#![no_std]
#![allocator]
// The minimum alignment guaranteed by the architecture.
const MIN_ALIGN: usize = 8;
#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
unsafe { imp::allocate(size, align) }
}
#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
unsafe { imp::deallocate(ptr, old_size, align) }
}
#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
old_size: usize,
size: usize,
align: usize)
-> *mut u8 {
unsafe { imp::reallocate(ptr, old_size, size, align) }
}
#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
old_size: usize,
size: usize,
align: usize)
-> usize {
unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}
#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
imp::usable_size(size, align)
}
mod imp {
extern crate libc;
use core::cmp;
use core::ptr;
use MIN_ALIGN;
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::malloc(size as libc::size_t) as *mut u8
} else {
aligned_malloc(size, align)
}
}
unsafe fn aligned_malloc(_size: usize, _align: usize) -> *mut u8 {
panic!("aligned_malloc not implemented")
}
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize,
size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
} else {
let new_ptr = allocate(size, align);
if !new_ptr.is_null() {
ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
deallocate(ptr, old_size, align);
}
new_ptr
}
}
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: usize,
_size: usize, _align: usize) -> usize {
old_size
}
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
libc::free(ptr as *mut libc::c_void)
}
pub fn usable_size(size: usize, _align: usize) -> usize {
size
}
}

View File

@ -0,0 +1,11 @@
[package]
authors = ["The ARTIQ Project Developers"]
name = "std_artiq"
version = "0.0.0"
[lib]
name = "std_artiq"
path = "lib.rs"
[dependencies]
alloc_artiq = { path = "../liballoc_artiq" }

View File

@ -0,0 +1,64 @@
#![feature(lang_items, asm, collections, libc, needs_panic_runtime)]
#![no_std]
#![needs_panic_runtime]
extern crate alloc_artiq;
extern crate collections;
extern crate libc;
pub mod prelude {
pub mod v1 {
pub use core::prelude::v1::*;
pub use collections::*;
}
}
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 {}:{}: ", file, line);
let _ = Console.write_fmt(args);
let _ = write!(Console, "\nwaiting 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 {}
}

View File

@ -0,0 +1,11 @@
#![no_std]
#[macro_use]
extern crate std_artiq as std;
use std::prelude::v1::*;
#[no_mangle]
pub extern "C" fn rust_main() {
println!("hello from rust!");
}

View File

@ -27,8 +27,9 @@ all: runtime.bin runtime.fbi
%.fbi: %.bin %.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $< @echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<
runtime.elf: $(OBJECTS) runtime.elf: $(OBJECTS) libartiq_rust.a
$(LD) $(LDFLAGS) \ $(LD) $(LDFLAGS) \
--gc-sections \
-T $(RUNTIME_DIRECTORY)/runtime.ld \ -T $(RUNTIME_DIRECTORY)/runtime.ld \
-N -o $@ \ -N -o $@ \
../libbase/crt0-$(CPU).o \ ../libbase/crt0-$(CPU).o \
@ -38,7 +39,8 @@ runtime.elf: $(OBJECTS)
-L../libm \ -L../libm \
-L../liballoc \ -L../liballoc \
-L../liblwip \ -L../liblwip \
-lbase -lm -lcompiler-rt -lalloc -llwip -Lcargo/or1k-unknown-none/debug/ \
-lartiq_rust -lbase -lm -lcompiler-rt -lalloc -llwip
@chmod -x $@ @chmod -x $@
ksupport.elf: $(OBJECTS_KSUPPORT) ksupport.elf: $(OBJECTS_KSUPPORT)
@ -58,6 +60,14 @@ ksupport.elf: $(OBJECTS_KSUPPORT)
ksupport_data.o: ksupport.elf ksupport_data.o: ksupport.elf
$(LD) -r -b binary -o $@ $< $(LD) -r -b binary -o $@ $<
libartiq_rust.a:
CARGO_TARGET_DIR="./cargo" \
cargo rustc --verbose \
--manifest-path $(RUNTIME_DIRECTORY)/../runtime.rs/Cargo.toml \
--target=or1k-unknown-none -- \
-C target-feature=+mul,+div,+ffl1,+cmov,+addc -C opt-level=s \
-L../libcompiler-rt
%.o: $(RUNTIME_DIRECTORY)/%.c %.o: $(RUNTIME_DIRECTORY)/%.c
$(compile) $(compile)

View File

@ -262,6 +262,8 @@ static int check_test_mode(void)
extern void _fheap, _eheap; extern void _fheap, _eheap;
extern void rust_main();
int main(void) int main(void)
{ {
irq_setmask(0); irq_setmask(0);
@ -276,6 +278,9 @@ int main(void)
puts("Press 't' to enter test mode..."); puts("Press 't' to enter test mode...");
blink_led(); blink_led();
puts("Calling Rust...");
rust_main();
if(check_test_mode()) { if(check_test_mode()) {
puts("Entering test mode."); puts("Entering test mode.");
test_main(); test_main();

View File

@ -15,7 +15,9 @@ requirements:
- migen 0.2 - migen 0.2
- misoc 0.2 - misoc 0.2
- llvm-or1k - llvm-or1k
- binutils-or1k-linux - binutils-or1k-linux >=2.27
- rust-core-or1k
- cargo
run: run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }} - artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }}

View File

@ -15,7 +15,9 @@ requirements:
- migen 0.2 - migen 0.2
- misoc 0.2 - misoc 0.2
- llvm-or1k - llvm-or1k
- binutils-or1k-linux - binutils-or1k-linux >=2.27
- rust-core-or1k
- cargo
run: run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }} - artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }}

View File

@ -15,7 +15,9 @@ requirements:
- migen 0.2 - migen 0.2
- misoc 0.2 - misoc 0.2
- llvm-or1k - llvm-or1k
- binutils-or1k-linux - binutils-or1k-linux >=2.27
- rust-core-or1k
- cargo
run: run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }} - artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }}

View File

@ -15,7 +15,9 @@ requirements:
- migen 0.2 - migen 0.2
- misoc 0.2 - misoc 0.2
- llvm-or1k - llvm-or1k
- binutils-or1k-linux - binutils-or1k-linux >=2.27
- rust-core-or1k
- cargo
run: run:
- artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }} - artiq {{ "{tag} py_{number}+git{hash}".format(tag=environ.get("GIT_DESCRIBE_TAG"), number=environ.get("GIT_DESCRIBE_NUMBER"), hash=environ.get("GIT_DESCRIBE_HASH")[1:]) if "GIT_DESCRIBE_TAG" in environ else "" }}