Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 62274a6c0d95
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2a7a8f91ca6f
Choose a head ref
  • 2 commits
  • 12 files changed
  • 1 contributor

Commits on Jan 18, 2017

  1. firmware: add satellite manager

    The code duplication with the runtime should be cleaned up later.
    sbourdeauducq committed Jan 18, 2017
    Copy the full SHA
    ce31ffd View commit details
  2. gateware: fix import

    sbourdeauducq committed Jan 18, 2017
    Copy the full SHA
    2a7a8f9 View commit details
12 changes: 12 additions & 0 deletions artiq/firmware/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion artiq/firmware/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["runtime", "libksupport"]
members = ["runtime", "libksupport", "satman"]
2 changes: 1 addition & 1 deletion artiq/firmware/runtime/lib.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ pub unsafe extern fn rust_main() {
BufferLogger::new(&mut LOG_BUFFER[..])
.register(move || {
board::clock::init();
info!("booting ARTIQ");
info!("ARTIQ runtime starting...");
info!("software version {}", GIT_COMMIT);
info!("gateware version {}", board::ident(&mut [0; 64]));

20 changes: 20 additions & 0 deletions artiq/firmware/satman/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
authors = ["M-Labs"]
name = "satman"
version = "0.0.0"
build = "build.rs"

[build-dependencies]
walkdir = "1.0"

[lib]
name = "satman"
crate-type = ["staticlib"]
path = "lib.rs"

[dependencies]
alloc_artiq = { path = "../liballoc_artiq" }
std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
board = { path = "../libboard" }
log = { version = "0.3", default-features = false }
log_buffer = { version = "1.0" }
49 changes: 49 additions & 0 deletions artiq/firmware/satman/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak

PYTHON ?= python3.5

OBJECTS := main.o

RUSTOUT := cargo/or1k-unknown-none/debug

CFLAGS += -I$(LIBALLOC_DIRECTORY)

LDFLAGS += --gc-sections \
-L../libcompiler-rt \
-L../libbase \
-L../liballoc

all: satman.bin satman.fbi

.PHONY: $(RUSTOUT)/libsatman.a
$(RUSTOUT)/libsatman.a:
RUSTFLAGS="-C target-feature=+mul,+div,+ffl1,+cmov,+addc -C opt-level=s -Cpanic=abort" \
CARGO_TARGET_DIR=$(realpath .)/cargo \
cargo build --target=or1k-unknown-none \
--manifest-path $(realpath $(SATMAN_DIRECTORY))/Cargo.toml

satman.elf: $(OBJECTS) $(RUSTOUT)/libsatman.a
$(LD) $(LDFLAGS) \
-T $(SATMAN_DIRECTORY)/satman.ld \
-o $@ \
$^ \
-lbase-nofloat -lcompiler-rt -lalloc
@chmod -x $@

%.o: $(SATMAN_DIRECTORY)/%.c
$(compile)

%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod -x $@

%.fbi: %.bin
@echo " MSCIMG " $@ && $(PYTHON) -m misoc.tools.mkmscimg -f -o $@ $<

clean:
$(RM) $(OBJECTS)
$(RM) satman.elf satman.bin satman.fbi .*~ *~
$(RM) -rf cargo

.PHONY: all clean
53 changes: 53 additions & 0 deletions artiq/firmware/satman/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern crate walkdir;

use std::env;
use std::fs::File;
use std::io::{Write, BufRead, BufReader};
use std::path::Path;
use std::process::Command;

use walkdir::WalkDir;

fn main() {
let out_dir = env::var("BUILDINC_DIRECTORY").unwrap();
let cfg_path = Path::new(&out_dir).join("generated").join("rust-cfg");
println!("cargo:rerun-if-changed={}", cfg_path.to_str().unwrap());

let f = BufReader::new(File::open(&cfg_path).unwrap());
for line in f.lines() {
println!("cargo:rustc-cfg={}", line.unwrap());
}

let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("git_info.rs");
let mut f = File::create(&dest_path).unwrap();

let id = git_describe().unwrap();
let id = id.split("-").collect::<Vec<_>>();
let id = format!("{}+{}.{}", id[0], id[1], id[2]);
writeln!(f, "const GIT_COMMIT: &'static str = {:?};", id).unwrap();

println!("cargo:rerun-if-changed=../../../.git/HEAD");
for entry in WalkDir::new("../../../.git/refs") {
let entry = entry.unwrap();
println!("cargo:rerun-if-changed={}", entry.path().display());
}
}

// Returns `None` if git is not available.
fn git_describe() -> Option<String> {
Command::new("git")
.arg("describe")
.arg("--tags")
.arg("--dirty")
.arg("--always")
.arg("--long")
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|mut s| {
let len = s.trim_right().len();
s.truncate(len);
s
})
}
93 changes: 93 additions & 0 deletions artiq/firmware/satman/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#![no_std]
#![feature(libc, const_fn, repr_simd, asm, lang_items)]

extern crate alloc_artiq;
#[macro_use]
extern crate std_artiq as std;
extern crate libc;
#[macro_use]
extern crate log;
extern crate log_buffer;
extern crate board;

use core::fmt::Write;
use logger::BufferLogger;

extern {
fn putchar(c: libc::c_int) -> libc::c_int;
fn readchar() -> libc::c_char;
fn readchar_nonblock() -> libc::c_int;
}

#[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);
}

#[no_mangle]
#[lang = "panic_fmt"]
pub 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 logger;

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; 65536] = [0; 65536];
BufferLogger::new(&mut LOG_BUFFER[..])
.register(move || {
board::clock::init();
info!("ARTIQ satellite manager starting...");
info!("software version {}", GIT_COMMIT);
info!("gateware version {}", board::ident(&mut [0; 64]));

loop {
}
})
}

#[no_mangle]
pub unsafe extern fn isr() {
use board::{irq, csr};
extern { fn uart_isr(); }

let irqs = irq::pending() & irq::get_mask();
if irqs & (1 << csr::UART_INTERRUPT) != 0 {
uart_isr()
}
}
83 changes: 83 additions & 0 deletions artiq/firmware/satman/logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use core::{mem, ptr};
use core::cell::{Cell, RefCell};
use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter};
use log_buffer::LogBuffer;
use board;

pub struct BufferLogger {
buffer: RefCell<LogBuffer<&'static mut [u8]>>,
trace_to_uart: Cell<bool>
}

unsafe impl Sync for BufferLogger {}

static mut LOGGER: *const BufferLogger = ptr::null();

impl BufferLogger {
pub fn new(buffer: &'static mut [u8]) -> BufferLogger {
BufferLogger {
buffer: RefCell::new(LogBuffer::new(buffer)),
trace_to_uart: Cell::new(true)
}
}

pub fn register<F: FnOnce()>(&self, f: F) {
// log::set_logger_raw captures a pointer to ourselves, so we must prevent
// ourselves from being moved or dropped after that function is called (and
// before log::shutdown_logger_raw is called).
unsafe {
log::set_logger_raw(|max_log_level| {
max_log_level.set(LogLevelFilter::Trace);
self as *const Log
}).expect("global logger can only be initialized once");
LOGGER = self;
}
f();
log::shutdown_logger_raw().unwrap();
unsafe {
LOGGER = ptr::null();
}
}

pub fn with_instance<R, F: FnOnce(&BufferLogger) -> R>(f: F) -> R {
f(unsafe { mem::transmute::<*const BufferLogger, &BufferLogger>(LOGGER) })
}

pub fn clear(&self) {
self.buffer.borrow_mut().clear()
}

pub fn extract<R, F: FnOnce(&str) -> R>(&self, f: F) -> R {
f(self.buffer.borrow_mut().extract())
}

pub fn disable_trace_to_uart(&self) {
if self.trace_to_uart.get() {
trace!("disabling tracing to UART; all further trace messages \
are sent to core log only");
self.trace_to_uart.set(false)
}
}
}

impl Log for BufferLogger {
fn enabled(&self, _metadata: &LogMetadata) -> bool {
true
}

fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
use core::fmt::Write;
writeln!(self.buffer.borrow_mut(),
"[{:12}us] {:>5}({}): {}",
board::clock::get_us(), record.level(), record.target(), record.args()).unwrap();

// Printing to UART is really slow, so avoid doing that when we have an alternative
// route to retrieve the debug messages.
if self.trace_to_uart.get() || record.level() <= LogLevel::Info {
println!("[{:12}us] {:>5}({}): {}",
board::clock::get_us(), record.level(), record.target(), record.args());
}
}
}
}
22 changes: 22 additions & 0 deletions artiq/firmware/satman/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <alloc.h>
#include <irq.h>
#include <uart.h>
#include <system.h>
#include <generated/csr.h>

extern void _fheap, _eheap;

extern void rust_main();

int main(void)
{
irq_setmask(0);
irq_setie(1);
uart_init();

alloc_give(&_fheap, &_eheap - &_fheap);

rust_main();

return 0;
}
Loading