diff --git a/artiq/runtime.rs/libstd_artiq/lib.rs b/artiq/runtime.rs/libstd_artiq/lib.rs index 9e95c2a24..e2fe3b9d8 100644 --- a/artiq/runtime.rs/libstd_artiq/lib.rs +++ b/artiq/runtime.rs/libstd_artiq/lib.rs @@ -29,7 +29,6 @@ pub mod prelude { } } -pub mod time; pub mod error; pub mod io; diff --git a/artiq/runtime.rs/libstd_artiq/time/duration.rs b/artiq/runtime.rs/libstd_artiq/time/duration.rs deleted file mode 100644 index c3d7bd1ed..000000000 --- a/artiq/runtime.rs/libstd_artiq/time/duration.rs +++ /dev/null @@ -1,117 +0,0 @@ -use core::ops::{Add, Sub, Mul, Div}; - -const MILLIS_PER_SEC: u64 = 1_000; -const NANOS_PER_MILLI: u32 = 1_000_000; - -/// A duration type to represent a span of time, typically used for system -/// timeouts. -/// -/// Each duration is composed of a number of seconds and nanosecond precision. -/// APIs binding a system timeout will typically round up the nanosecond -/// precision if the underlying system does not support that level of precision. -/// -/// Durations implement many common traits, including `Add`, `Sub`, and other -/// ops traits. Currently a duration may only be inspected for its number of -/// seconds and its nanosecond precision. -/// -/// # Examples -/// -/// ``` -/// use std::time::Duration; -/// -/// let five_seconds = Duration::new(5, 0); -/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5); -/// -/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5); -/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5); -/// -/// let ten_millis = Duration::from_millis(10); -/// ``` -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub struct Duration { - millis: u64 -} - -impl Duration { - /// Creates a new `Duration` from the specified number of seconds and - /// additional nanosecond precision. - /// - /// If the nanoseconds is greater than 1 billion (the number of nanoseconds - /// in a second), then it will carry over into the seconds provided. - pub fn new(secs: u64, nanos: u32) -> Duration { - Duration { millis: secs * MILLIS_PER_SEC + (nanos / NANOS_PER_MILLI) as u64 } - } - - /// Creates a new `Duration` from the specified number of seconds. - pub fn from_secs(secs: u64) -> Duration { - Duration { millis: secs * MILLIS_PER_SEC } - } - - /// Creates a new `Duration` from the specified number of milliseconds. - pub fn from_millis(millis: u64) -> Duration { - Duration { millis: millis } - } - - /// Returns the number of whole milliseconds represented by this duration. - pub fn as_millis(&self) -> u64 { self.millis } - - /// Returns the number of whole seconds represented by this duration. - /// - /// The extra precision represented by this duration is ignored (e.g. extra - /// nanoseconds are not represented in the returned value). - pub fn as_secs(&self) -> u64 { - self.millis / MILLIS_PER_SEC - } - - /// Returns the nanosecond precision represented by this duration. - /// - /// This method does **not** return the length of the duration when - /// represented by nanoseconds. The returned number always represents a - /// fractional portion of a second (e.g. it is less than one billion). - pub fn subsec_nanos(&self) -> u32 { - (self.millis % MILLIS_PER_SEC) as u32 * NANOS_PER_MILLI - } -} - -impl Add for Duration { - type Output = Duration; - - fn add(self, rhs: Duration) -> Duration { - Duration { - millis: self.millis.checked_add(rhs.millis) - .expect("overflow when adding durations") - } - } -} - -impl Sub for Duration { - type Output = Duration; - - fn sub(self, rhs: Duration) -> Duration { - Duration { - millis: self.millis.checked_sub(rhs.millis) - .expect("overflow when subtracting durations") - } - } -} - -impl Mul for Duration { - type Output = Duration; - - fn mul(self, rhs: u32) -> Duration { - Duration { - millis: self.millis.checked_mul(rhs as u64) - .expect("overflow when multiplying duration") - } - } -} - -impl Div for Duration { - type Output = Duration; - - fn div(self, rhs: u32) -> Duration { - Duration { - millis: self.millis / (rhs as u64) - } - } -} diff --git a/artiq/runtime.rs/libstd_artiq/time/instant.rs b/artiq/runtime.rs/libstd_artiq/time/instant.rs deleted file mode 100644 index 2282b0f5d..000000000 --- a/artiq/runtime.rs/libstd_artiq/time/instant.rs +++ /dev/null @@ -1,81 +0,0 @@ -use core::ops::{Add, Sub}; -use time::duration::Duration; - -/// A measurement of a monotonically increasing clock. -/// -/// Instants are always guaranteed to be greater than any previously measured -/// instant when created, and are often useful for tasks such as measuring -/// benchmarks or timing how long an operation takes. -/// -/// Note, however, that instants are not guaranteed to be **steady**. In other -/// words, each tick of the underlying clock may not be the same length (e.g. -/// some seconds may be longer than others). An instant may jump forwards or -/// experience time dilation (slow down or speed up), but it will never go -/// backwards. -/// -/// Instants are opaque types that can only be compared to one another. There is -/// no method to get "the number of seconds" from an instant. Instead, it only -/// allows measuring the duration between two instants (or comparing two -/// instants). -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Instant { - millis: u64 -} - -impl Instant { - /// Returns an instant corresponding to "now". - pub fn now() -> Instant { - extern { - fn clock_get_ms() -> i64; - } - - Instant { millis: unsafe { clock_get_ms() as u64 } } - } - - /// Returns the amount of time elapsed from another instant to this one. - /// - /// # Panics - /// - /// This function will panic if `earlier` is later than `self`, which should - /// only be possible if `earlier` was created after `self`. Because - /// `Instant` is monotonic, the only time that this should happen should be - /// a bug. - pub fn duration_from_earlier(&self, earlier: Instant) -> Duration { - let millis = self.millis.checked_sub(earlier.millis) - .expect("`earlier` is later than `self`"); - Duration::from_millis(millis) - } - - /// Returns the amount of time elapsed since this instant was created. - /// - /// # Panics - /// - /// This function may panic if the current time is earlier than this - /// instant, which is something that can happen if an `Instant` is - /// produced synthetically. - pub fn elapsed(&self) -> Duration { - Instant::now().duration_from_earlier(*self) - } -} - -impl Add for Instant { - type Output = Instant; - - fn add(self, other: Duration) -> Instant { - Instant { - millis: self.millis.checked_add(other.as_millis()) - .expect("overflow when adding duration to instant") - } - } -} - -impl Sub for Instant { - type Output = Instant; - - fn sub(self, other: Duration) -> Instant { - Instant { - millis: self.millis.checked_sub(other.as_millis()) - .expect("overflow when subtracting duration from instant") - } - } -} diff --git a/artiq/runtime.rs/libstd_artiq/time/mod.rs b/artiq/runtime.rs/libstd_artiq/time/mod.rs deleted file mode 100644 index c1269983d..000000000 --- a/artiq/runtime.rs/libstd_artiq/time/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use self::duration::Duration; -pub use self::instant::Instant; - -mod duration; -mod instant; diff --git a/artiq/runtime.rs/src/lib.rs b/artiq/runtime.rs/src/lib.rs index a9da393ec..45728f469 100644 --- a/artiq/runtime.rs/src/lib.rs +++ b/artiq/runtime.rs/src/lib.rs @@ -69,3 +69,13 @@ pub unsafe extern fn rust_main() { } }) } + +#[no_mangle] +pub fn sys_now() -> u32 { + clock::get_ms() as u32 +} + +#[no_mangle] +pub fn sys_jiffies() -> u32 { + clock::get_ms() as u32 +} diff --git a/artiq/runtime.rs/src/sched.rs b/artiq/runtime.rs/src/sched.rs index 1e84cd73e..4e698f94b 100644 --- a/artiq/runtime.rs/src/sched.rs +++ b/artiq/runtime.rs/src/sched.rs @@ -2,16 +2,16 @@ use std::cell::RefCell; use std::vec::Vec; -use std::time::{Instant, Duration}; use std::io::{Read, Write, Result, Error, ErrorKind}; use fringe::OwnedStack; use fringe::generator::{Generator, Yielder, State as GeneratorState}; use lwip; +use clock; use urc::Urc; #[derive(Debug)] struct WaitRequest { - timeout: Option, + timeout: Option, event: Option } @@ -106,7 +106,7 @@ impl Scheduler { if self.threads.len() == 0 { return } - let now = Instant::now(); + let now = clock::get_ms(); let start_index = self.index; loop { @@ -214,9 +214,9 @@ unsafe impl Send for WaitEvent {} pub struct Waiter<'a>(&'a Yielder); impl<'a> Waiter<'a> { - pub fn sleep(&self, duration: Duration) -> Result<()> { + pub fn sleep(&self, duration_ms: u64) -> Result<()> { let request = WaitRequest { - timeout: Some(Instant::now() + duration), + timeout: Some(clock::get_ms() + duration_ms), event: None }; diff --git a/artiq/runtime/Makefile b/artiq/runtime/Makefile index 0f8aec3cd..5bc5325f4 100644 --- a/artiq/runtime/Makefile +++ b/artiq/runtime/Makefile @@ -3,9 +3,7 @@ include $(MISOC_DIRECTORY)/software/common.mak PYTHON ?= python3.5 -OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \ - session.o log.o analyzer.o moninj.o net_server.o \ - ksupport_data.o kloader.o main.o +OBJECTS := isr.o flash_storage.o ksupport_data.o main.o OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \ rtio.o dds.o i2c.o diff --git a/artiq/runtime/analyzer.c b/artiq/runtime/analyzer.c deleted file mode 100644 index 84e15b929..000000000 --- a/artiq/runtime/analyzer.c +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include - -#include "log.h" -#include "analyzer.h" - - -#ifdef CSR_RTIO_ANALYZER_BASE - -struct analyzer_header { - unsigned int sent_bytes; - unsigned long long int total_byte_count; - unsigned char overflow_occured; - unsigned char log_channel; - unsigned char dds_onehot_sel; -} __attribute__((packed)); - - -#define ANALYZER_BUFFER_SIZE (512*1024) - -static struct analyzer_header analyzer_header; -static char analyzer_buffer[ANALYZER_BUFFER_SIZE] __attribute__((aligned(64))); - -static void arm(void) -{ - rtio_analyzer_message_encoder_overflow_reset_write(1); - rtio_analyzer_dma_base_address_write((unsigned int)analyzer_buffer); - rtio_analyzer_dma_last_address_write((unsigned int)analyzer_buffer + ANALYZER_BUFFER_SIZE - 1); - rtio_analyzer_dma_reset_write(1); - rtio_analyzer_enable_write(1); -} - -static void disarm(void) -{ - rtio_analyzer_enable_write(0); - while(rtio_analyzer_busy_read()); - flush_cpu_dcache(); - flush_l2_cache(); -} - -void analyzer_init(void) -{ - arm(); -} - -enum { - SEND_STATE_HEADER, - SEND_STATE_POST_POINTER, /* send from pointer to end of buffer */ - SEND_STATE_PRE_POINTER, /* send from start of buffer to pointer-1 */ - SEND_STATE_TERMINATE -}; - -static int send_state; -static int pointer; -static int wraparound; -static int offset_consumed; -static int offset_sent; - -void analyzer_start(void) -{ - disarm(); - - analyzer_header.total_byte_count = rtio_analyzer_dma_byte_count_read(); - pointer = analyzer_header.total_byte_count % ANALYZER_BUFFER_SIZE; - wraparound = analyzer_header.total_byte_count >= ANALYZER_BUFFER_SIZE; - - if(wraparound) - analyzer_header.sent_bytes = ANALYZER_BUFFER_SIZE; - else - analyzer_header.sent_bytes = analyzer_header.total_byte_count; - - analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read(); - analyzer_header.log_channel = CONFIG_RTIO_LOG_CHANNEL; -#ifdef CONFIG_DDS_ONEHOT_SEL - analyzer_header.dds_onehot_sel = 1; -#else - analyzer_header.dds_onehot_sel = 0; -#endif - - offset_consumed = 0; - offset_sent = 0; - send_state = SEND_STATE_HEADER; -} - -void analyzer_end(void) -{ - arm(); -} - -int analyzer_input(void *data, int length) -{ - core_log("no input should be received by analyzer, dropping connection\n"); - return -1; -} - -void analyzer_poll(void **data, int *length, int *close_flag) -{ - *close_flag = 0; - switch(send_state) { - case SEND_STATE_HEADER: - *length = sizeof(struct analyzer_header) - offset_consumed; - *data = (char *)&analyzer_header + offset_consumed; - break; - case SEND_STATE_POST_POINTER: - *length = ANALYZER_BUFFER_SIZE - pointer - offset_consumed; - *data = analyzer_buffer + pointer + offset_consumed; - break; - case SEND_STATE_PRE_POINTER: - *length = pointer - offset_consumed; - *data = analyzer_buffer + offset_consumed; - break; - case SEND_STATE_TERMINATE: - *length = -1; - break; - default: - *length = 0; - break; - } -} - -void analyzer_ack_consumed(int length) -{ - offset_consumed += length; -} - -void analyzer_ack_sent(int length) -{ - offset_sent += length; - switch(send_state) { - case SEND_STATE_HEADER: - if(offset_sent >= sizeof(struct analyzer_header)) { - offset_consumed = 0; - offset_sent = 0; - if(wraparound) - send_state = SEND_STATE_POST_POINTER; - else { - if(pointer) - send_state = SEND_STATE_PRE_POINTER; - else - send_state = SEND_STATE_TERMINATE; - } - } - break; - case SEND_STATE_POST_POINTER: - if(pointer + offset_consumed >= ANALYZER_BUFFER_SIZE) { - offset_consumed = 0; - offset_sent = 0; - send_state = SEND_STATE_PRE_POINTER; - } - break; - case SEND_STATE_PRE_POINTER: - if(offset_sent >= pointer) - send_state = SEND_STATE_TERMINATE; - break; - } -} - -#endif diff --git a/artiq/runtime/analyzer.h b/artiq/runtime/analyzer.h deleted file mode 100644 index c94b664b2..000000000 --- a/artiq/runtime/analyzer.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ANALYZER_H -#define __ANALYZER_H - -void analyzer_init(void); - -void analyzer_start(void); -void analyzer_end(void); - -int analyzer_input(void *data, int length); -void analyzer_poll(void **data, int *length, int *close_flag); -void analyzer_ack_consumed(int length); -void analyzer_ack_sent(int length); - -#endif /* __ANALYZER_H */ diff --git a/artiq/runtime/clock.c b/artiq/runtime/clock.c deleted file mode 100644 index bbcf87d7c..000000000 --- a/artiq/runtime/clock.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -#include "log.h" -#include "clock.h" - - -void clock_init(void) -{ - timer0_en_write(0); - timer0_load_write(0x7fffffffffffffffLL); - timer0_reload_write(0x7fffffffffffffffLL); - timer0_en_write(1); -} - -long long int clock_get_ms(void) -{ - long long int clock_sys; - long long int clock_ms; - - timer0_update_value_write(1); - clock_sys = 0x7fffffffffffffffLL - timer0_value_read(); - - clock_ms = clock_sys/(CONFIG_CLOCK_FREQUENCY/1000); - return clock_ms; -} - -void busywait_us(long long int us) -{ - long long int threshold; - - timer0_update_value_write(1); - threshold = timer0_value_read() - us*CONFIG_CLOCK_FREQUENCY/1000000LL; - while(timer0_value_read() > threshold) - timer0_update_value_write(1); -} - -struct watchdog { - int active; - long long int threshold; -}; - -static struct watchdog watchdogs[MAX_WATCHDOGS]; - -void watchdog_init(void) -{ - int i; - - for(i=0;i= MAX_WATCHDOGS)) - return; - watchdogs[id].active = 0; -} - -int watchdog_expired(void) -{ - int i; - long long int t; - - t = 0x7fffffffffffffffLL; - for(i=0;i t; -} diff --git a/artiq/runtime/clock.h b/artiq/runtime/clock.h deleted file mode 100644 index 4f4895443..000000000 --- a/artiq/runtime/clock.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __CLOCK_H -#define __CLOCK_H - -void clock_init(void); -long long int clock_get_ms(void); -void busywait_us(long long us); - -#define MAX_WATCHDOGS 16 - -void watchdog_init(void); -int watchdog_set(int ms); -void watchdog_clear(int id); -int watchdog_expired(void); - -#endif /* __CLOCK_H */ diff --git a/artiq/runtime/dds.c b/artiq/runtime/dds.c index 718d32bcd..5b221ecf9 100644 --- a/artiq/runtime/dds.c +++ b/artiq/runtime/dds.c @@ -6,7 +6,6 @@ #include "artiq_personality.h" #include "rtio.h" -#include "log.h" #include "dds.h" #define DURATION_WRITE (5 << CONFIG_RTIO_FINE_TS_WIDTH) diff --git a/artiq/runtime/flash_storage.c b/artiq/runtime/flash_storage.c index dfa74906e..3e18151d6 100644 --- a/artiq/runtime/flash_storage.c +++ b/artiq/runtime/flash_storage.c @@ -9,7 +9,6 @@ #include #include -#include "log.h" #include "flash_storage.h" #if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE) @@ -63,24 +62,24 @@ static int record_iter_next(struct iter_state *is, struct record *record, int *f return 0; if(record->size < 6) { - core_log("flash_storage might be corrupted: record size is %u (<6) at address %08x\n", - record->size, record->raw_record); + // core_log("flash_storage might be corrupted: record size is %u (<6) at address %08x\n", + // record->size, record->raw_record); if(fatal) *fatal = 1; return 0; } if(is->seek > is->buf_len - sizeof(record->size) - 2) { /* 2 is the minimum key length */ - core_log("flash_storage might be corrupted: END_MARKER missing at the end of " - "the storage sector\n"); + // core_log("flash_storage might be corrupted: END_MARKER missing at the end of " + // "the storage sector\n"); if(fatal) *fatal = 1; return 0; } if(record->size > is->buf_len - is->seek) { - core_log("flash_storage might be corrupted: invalid record_size %d at address %08x\n", - record->size, record->raw_record); + // core_log("flash_storage might be corrupted: invalid record_size %d at address %08x\n", + // record->size, record->raw_record); if(fatal) *fatal = 1; return 0; @@ -90,8 +89,8 @@ static int record_iter_next(struct iter_state *is, struct record *record, int *f record->key_len = strnlen(record->key, record->size - sizeof(record->size)) + 1; if(record->key_len == record->size - sizeof(record->size) + 1) { - core_log("flash_storage might be corrupted: invalid key length at address %08x\n", - record->raw_record); + // core_log("flash_storage might be corrupted: invalid key length at address %08x\n", + // record->raw_record); if(fatal) *fatal = 1; return 0; @@ -265,7 +264,7 @@ int fs_write(const char *key, const void *buffer, unsigned int buf_len) return 0; // Storage is definitely full. fatal_error: - core_log("fatal error: flash storage might be corrupted\n"); + // core_log("fatal error: flash storage might be corrupted\n"); return 0; } @@ -295,8 +294,8 @@ unsigned int fs_read(const char *key, void *buffer, unsigned int buf_len, unsign } } - if(fatal) - core_log("fatal error: flash storage might be corrupted\n"); + // if(fatal) + // core_log("fatal error: flash storage might be corrupted\n"); return read_length; } diff --git a/artiq/runtime/kloader.c b/artiq/runtime/kloader.c deleted file mode 100644 index 04cd6b90a..000000000 --- a/artiq/runtime/kloader.c +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include - -#include "kloader.h" -#include "log.h" -#include "clock.h" -#include "flash_storage.h" -#include "mailbox.h" -#include "messages.h" - -int kloader_load_library(const void *library) -{ - if(!kernel_cpu_reset_read()) { - core_log("BUG: attempted to load kernel library while kernel CPU is running\n"); - return 0; - } - - // Stop kernel CPU before messing with its code. - kernel_cpu_reset_write(1); - - // Load kernel support code. - extern void _binary_ksupport_elf_start, _binary_ksupport_elf_end; - memcpy((void *)(KERNELCPU_EXEC_ADDRESS - KSUPPORT_HEADER_SIZE), - &_binary_ksupport_elf_start, - &_binary_ksupport_elf_end - &_binary_ksupport_elf_start); - - // Start kernel CPU. - kernel_cpu_reset_write(0); - - struct msg_load_request request = { - .type = MESSAGE_TYPE_LOAD_REQUEST, - .library = library, - }; - mailbox_send(&request); - - struct msg_load_reply *reply = mailbox_wait_and_receive(); - - if(reply->type != MESSAGE_TYPE_LOAD_REPLY) { - core_log("BUG: unexpected reply to load/run request\n"); - return 0; - } - - if(reply->error != NULL) { - core_log("cannot load kernel: %s\n", reply->error); - return 0; - } - - return 1; -} - -void kloader_start_kernel() -{ - if(kernel_cpu_reset_read()) { - core_log("BUG: attempted to load kernel library while kernel CPU is stopped\n"); - return; - } - - mailbox_acknowledge(); -} - -static int kloader_start_flash_kernel(char *key) -{ -#if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE) - char buffer[32*1024]; - unsigned int length, remain; - - length = fs_read(key, buffer, sizeof(buffer), &remain); - if(length <= 0) - return 0; - - if(remain) { - core_log("ERROR: kernel %s is too large\n", key); - return 0; - } - - if(!kloader_load_library(buffer)) - return 0; - kloader_start_kernel(); - return 1; -#else - return 0; -#endif -} - -int kloader_start_startup_kernel(void) -{ - return kloader_start_flash_kernel("startup_kernel"); -} - -int kloader_start_idle_kernel(void) -{ - return kloader_start_flash_kernel("idle_kernel"); -} - -void kloader_stop(void) -{ - kernel_cpu_reset_write(1); - mailbox_acknowledge(); -} - -int kloader_validate_kpointer(void *p) -{ - unsigned int v = (unsigned int)p; - if((v < KERNELCPU_EXEC_ADDRESS) || (v > KERNELCPU_LAST_ADDRESS)) { - core_log("Received invalid pointer from kernel CPU: 0x%08x\n", v); - return 0; - } - return 1; -} - -int kloader_is_essential_kmsg(int msgtype) -{ - switch(msgtype) { - case MESSAGE_TYPE_NOW_INIT_REQUEST: - case MESSAGE_TYPE_NOW_SAVE: - case MESSAGE_TYPE_LOG: - case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: - case MESSAGE_TYPE_WATCHDOG_CLEAR: - return 1; - default: - return 0; - } -} - -static long long int now = 0; - -void kloader_service_essential_kmsg(void) -{ - struct msg_base *umsg; - - umsg = mailbox_receive(); - if(umsg) { - if(!kloader_validate_kpointer(umsg)) - return; - switch(umsg->type) { - case MESSAGE_TYPE_NOW_INIT_REQUEST: { - struct msg_now_init_reply reply; - - reply.type = MESSAGE_TYPE_NOW_INIT_REPLY; - reply.now = now; - mailbox_send_and_wait(&reply); - break; - } - case MESSAGE_TYPE_NOW_SAVE: { - struct msg_now_save *msg = (struct msg_now_save *)umsg; - - now = msg->now; - mailbox_acknowledge(); - break; - } - case MESSAGE_TYPE_LOG: { - struct msg_log *msg = (struct msg_log *)umsg; - - core_log("%s", msg->buf); - mailbox_acknowledge(); - break; - } - case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: { - struct msg_watchdog_set_request *msg = (struct msg_watchdog_set_request *)umsg; - struct msg_watchdog_set_reply reply; - - reply.type = MESSAGE_TYPE_WATCHDOG_SET_REPLY; - reply.id = watchdog_set(msg->ms); - mailbox_send_and_wait(&reply); - break; - } - case MESSAGE_TYPE_WATCHDOG_CLEAR: { - struct msg_watchdog_clear *msg = (struct msg_watchdog_clear *)umsg; - - watchdog_clear(msg->id); - mailbox_acknowledge(); - break; - } - default: - /* handled elsewhere */ - break; - } - } -} diff --git a/artiq/runtime/kloader.h b/artiq/runtime/kloader.h deleted file mode 100644 index a330c4660..000000000 --- a/artiq/runtime/kloader.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __KLOADER_H -#define __KLOADER_H - -#define KERNELCPU_EXEC_ADDRESS 0x42000000 -#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000 -#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024) -#define KSUPPORT_HEADER_SIZE 0x80 - -int kloader_load_library(const void *code); - -int kloader_start_startup_kernel(void); -int kloader_start_idle_kernel(void); -void kloader_start_kernel(void); -void kloader_stop(void); - -int kloader_validate_kpointer(void *p); -int kloader_is_essential_kmsg(int msgtype); -void kloader_service_essential_kmsg(void); - -#endif /* __KLOADER_H */ diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index ff454440f..5de733c5e 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -9,7 +9,6 @@ #include #include "ksupport.h" -#include "kloader.h" #include "mailbox.h" #include "messages.h" #include "artiq_personality.h" @@ -17,6 +16,11 @@ #include "dds.h" #include "i2c.h" +#define KERNELCPU_EXEC_ADDRESS 0x42000000 +#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000 +#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024) +#define KSUPPORT_HEADER_SIZE 0x80 + double round(double x); double sqrt(double x); diff --git a/artiq/runtime/log.c b/artiq/runtime/log.c deleted file mode 100644 index 5779d8c94..000000000 --- a/artiq/runtime/log.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "log.h" - -static int buffer_cursor; -static char buffer[LOG_BUFFER_SIZE]; - -void core_log(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - core_log_va(fmt, args); - va_end(args); -} - -void core_log_va(const char *fmt, va_list args) -{ - char outbuf[256]; - int len = vscnprintf(outbuf, sizeof(outbuf), fmt, args); - - for(int i = 0; i < len; i++) { - buffer[buffer_cursor] = outbuf[i]; - buffer_cursor = (buffer_cursor + 1) % LOG_BUFFER_SIZE; - } - -#ifdef CSR_ETHMAC_BASE - /* Since main comms are over ethernet, the serial port - * is free for us to use. */ - putsnonl(outbuf); -#endif -} - -void core_log_get(char *outbuf) -{ - int j = buffer_cursor; - for(int i = 0; i < LOG_BUFFER_SIZE; i++) { - outbuf[i] = buffer[j]; - j = (j + 1) % LOG_BUFFER_SIZE; - } -} - -void core_log_clear() -{ - memset(buffer, 0, sizeof(buffer)); -} diff --git a/artiq/runtime/log.h b/artiq/runtime/log.h deleted file mode 100644 index fcb1fcf4e..000000000 --- a/artiq/runtime/log.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __LOG_H -#define __LOG_H - -#include - -#define LOG_BUFFER_SIZE 4096 - -void core_log(const char *fmt, ...); -void core_log_va(const char *fmt, va_list args); -void core_log_get(char *outbuf); -void core_log_clear(void); - -#endif /* __LOG_H */ diff --git a/artiq/runtime/main.c b/artiq/runtime/main.c index bf1091526..d5db5e5dc 100644 --- a/artiq/runtime/main.c +++ b/artiq/runtime/main.c @@ -24,24 +24,7 @@ #include #endif -#include "kloader.h" #include "flash_storage.h" -#include "clock.h" -#include "rtiocrg.h" -#include "net_server.h" -#include "session.h" -#include "analyzer.h" -#include "moninj.h" - -u32_t sys_now(void) -{ - return clock_get_ms(); -} - -u32_t sys_jiffies(void) -{ - return clock_get_ms(); -} static struct netif netif; @@ -182,53 +165,6 @@ void network_init(void) #endif /* CSR_ETHMAC_BASE */ -static struct net_server_instance session_inst = { - .port = 1381, - .start = session_start, - .end = session_end, - .input = session_input, - .poll = session_poll, - .ack_consumed = session_ack_consumed, - .ack_sent = session_ack_sent -}; - -#ifdef CSR_RTIO_ANALYZER_BASE -static struct net_server_instance analyzer_inst = { - .port = 1382, - .start = analyzer_start, - .end = analyzer_end, - .input = analyzer_input, - .poll = analyzer_poll, - .ack_consumed = analyzer_ack_consumed, - .ack_sent = analyzer_ack_sent -}; -#endif - -static void regular_main(void) -{ - puts("ARTIQ runtime built "__DATE__" "__TIME__"\n"); - - clock_init(); - rtiocrg_init(); - session_startup_kernel(); - - puts("Accepting network sessions."); - network_init(); - net_server_init(&session_inst); -#ifdef CSR_RTIO_ANALYZER_BASE - analyzer_init(); - net_server_init(&analyzer_inst); -#endif - moninj_init(); - - session_end(); - while(1) { - lwip_service(); - kloader_service_essential_kmsg(); - net_server_service(); - } -} - extern void _fheap, _eheap; extern void rust_main(); @@ -249,8 +185,7 @@ int main(void) alloc_give(&_fheap, &_eheap - &_fheap); - // rust_main(); - regular_main(); + rust_main(); return 0; } diff --git a/artiq/runtime/moninj.c b/artiq/runtime/moninj.c deleted file mode 100644 index 67116626f..000000000 --- a/artiq/runtime/moninj.c +++ /dev/null @@ -1,166 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "moninj.h" - -enum { - MONINJ_REQ_MONITOR = 1, - MONINJ_REQ_TTLSET = 2 -}; - -enum { - MONINJ_TTL_MODE_EXP = 0, - MONINJ_TTL_MODE_1 = 1, - MONINJ_TTL_MODE_0 = 2, - MONINJ_TTL_MODE_IN = 3 -}; - -enum { - MONINJ_TTL_OVERRIDE_ENABLE = 0, - MONINJ_TTL_OVERRIDE_O = 1, - MONINJ_TTL_OVERRIDE_OE = 2 -}; - -static struct udp_pcb *listen_pcb; - -struct monitor_reply { - long long int ttl_levels; - long long int ttl_oes; - long long int ttl_overrides; - unsigned short int dds_rtio_first_channel; - unsigned short int dds_channels_per_bus; -#if ((defined CONFIG_RTIO_DDS_COUNT) && (CONFIG_RTIO_DDS_COUNT > 0)) - unsigned int dds_ftws[CONFIG_RTIO_DDS_COUNT*CONFIG_DDS_CHANNELS_PER_BUS]; -#endif -} __attribute__((packed)); - -static void moninj_monitor(const ip_addr_t *addr, u16_t port) -{ - struct monitor_reply reply; - int i; - struct pbuf *reply_p; - - reply.ttl_levels = 0; - reply.ttl_oes = 0; - reply.ttl_overrides = 0; - for(i=0;i 0)) - int j; - - reply.dds_rtio_first_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL; - reply.dds_channels_per_bus = CONFIG_DDS_CHANNELS_PER_BUS; - for(j=0;jpayload, &reply, sizeof(struct monitor_reply)); - udp_sendto(listen_pcb, reply_p, addr, port); - pbuf_free(reply_p); -} - -static void moninj_ttlset(int channel, int mode) -{ - rtio_moninj_inj_chan_sel_write(channel); - switch(mode) { - case MONINJ_TTL_MODE_EXP: - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); - rtio_moninj_inj_value_write(0); - break; - case MONINJ_TTL_MODE_1: - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O); - rtio_moninj_inj_value_write(1); - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); - rtio_moninj_inj_value_write(1); - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); - rtio_moninj_inj_value_write(1); - break; - case MONINJ_TTL_MODE_0: - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_O); - rtio_moninj_inj_value_write(0); - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); - rtio_moninj_inj_value_write(1); - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); - rtio_moninj_inj_value_write(1); - break; - case MONINJ_TTL_MODE_IN: - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_OE); - rtio_moninj_inj_value_write(0); - rtio_moninj_inj_override_sel_write(MONINJ_TTL_OVERRIDE_ENABLE); - rtio_moninj_inj_value_write(1); - break; - default: - core_log("unknown TTL mode %d\n", mode); - break; - } -} - -static void moninj_recv(void *arg, struct udp_pcb *upcb, struct pbuf *req, - const ip_addr_t *addr, u16_t port) -{ - char *p = (char *)req->payload; - - if(req->len >= 1) { - switch(p[0]) { - case MONINJ_REQ_MONITOR: - moninj_monitor(addr, port); - break; - case MONINJ_REQ_TTLSET: - if(req->len < 3) - break; - moninj_ttlset(p[1], p[2]); - break; - default: - break; - } - } - pbuf_free(req); /* beware: addr may point into the req pbuf */ -} - -void moninj_init(void) -{ - listen_pcb = udp_new(); - if(!listen_pcb) { - core_log("Failed to create UDP listening PCB\n"); - return; - } - udp_bind(listen_pcb, IP_ADDR_ANY, 3250); - udp_recv(listen_pcb, moninj_recv, NULL); -} diff --git a/artiq/runtime/moninj.h b/artiq/runtime/moninj.h deleted file mode 100644 index 1224b3b6e..000000000 --- a/artiq/runtime/moninj.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __MONINJ_H -#define __MONINJ_H - -void moninj_init(void); - -#endif /* __MONINJ_H */ diff --git a/artiq/runtime/net_server.c b/artiq/runtime/net_server.c deleted file mode 100644 index 4d09f0cf3..000000000 --- a/artiq/runtime/net_server.c +++ /dev/null @@ -1,227 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "net_server.h" - -struct net_server_connstate { - struct net_server_instance *instance; - int magic_recognized; - struct pbuf *rp; - int rp_offset; -}; - -static struct net_server_connstate *cs_new(struct net_server_instance *instance) -{ - struct net_server_connstate *cs; - - cs = (struct net_server_connstate *)mem_malloc(sizeof(struct net_server_connstate)); - if(!cs) - return NULL; - cs->instance = instance; - cs->magic_recognized = 0; - cs->rp = NULL; - cs->rp_offset = 0; - return cs; -} - -static void cs_free(struct net_server_connstate *cs) -{ - if(cs->rp) - pbuf_free(cs->rp); - mem_free(cs); -} - -static const char net_server_magic[] = "ARTIQ coredev\n"; - -static int magic_ok(struct net_server_connstate *cs) -{ - return cs->magic_recognized >= 14; -} - -static void net_server_close(struct net_server_connstate *cs, struct tcp_pcb *pcb) -{ - struct net_server_instance *instance; - - instance = cs->instance; - if(cs == instance->open_session_cs) { - instance->end(); - instance->open_session_cs = NULL; - instance->open_session_pcb = NULL; - } - - if(pcb) { - /* lwip loves to call back with broken pointers. Prevent that. */ - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_sent(pcb, NULL); - tcp_err(pcb, NULL); - - tcp_close(pcb); - } - cs_free(cs); -} - -static err_t net_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct net_server_connstate *cs; - - cs = (struct net_server_connstate *)arg; - if(p) { - if(cs->rp) - pbuf_cat(cs->rp, p); - else { - cs->rp = p; - cs->rp_offset = 0; - } - } else - net_server_close(cs, pcb); - return ERR_OK; -} - -static err_t net_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct net_server_connstate *cs; - - cs = (struct net_server_connstate *)arg; - cs->instance->ack_sent(len); - return ERR_OK; -} - -static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb) -{ - struct net_server_connstate *cs; - struct net_server_instance *instance; - int remaining_in_pbuf; - char *rpp; - struct pbuf *next; - int r; - - cs = (struct net_server_connstate *)arg; - instance = cs->instance; - - /* Reader interface */ - while(cs->rp) { - remaining_in_pbuf = cs->rp->len - cs->rp_offset; - rpp = (char *)cs->rp->payload; - while(remaining_in_pbuf > 0) { - if(cs == instance->open_session_cs) { - r = instance->input(&rpp[cs->rp_offset], remaining_in_pbuf); - if(r > 0) { - tcp_recved(pcb, r); - cs->rp_offset += r; - remaining_in_pbuf -= r; - } else if(r == 0) - return; - else - net_server_close(cs, pcb); - } else { - if(rpp[cs->rp_offset] == net_server_magic[cs->magic_recognized]) { - cs->magic_recognized++; - if(magic_ok(cs)) { - if(instance->open_session_cs) - net_server_close(instance->open_session_cs, - instance->open_session_pcb); - instance->start(); - instance->open_session_cs = cs; - instance->open_session_pcb = pcb; - tcp_sent(pcb, net_server_sent); - } - } else { - net_server_close(cs, pcb); - return; - } - remaining_in_pbuf--; - cs->rp_offset++; - tcp_recved(pcb, 1); - } - } - next = cs->rp->next; - if(cs->rp->tot_len != cs->rp->len) { - pbuf_ref(next); - pbuf_free(cs->rp); - cs->rp = next; - cs->rp_offset = 0; - } else { - pbuf_free(cs->rp); - cs->rp = NULL; - } - } - - /* Writer interface */ - if(cs == instance->open_session_cs) { - void *data; - int len, sndbuf, close_flag; - - cs->instance->poll(&data, &len, &close_flag); - if(len > 0) { - sndbuf = tcp_sndbuf(pcb); - if(len > sndbuf) - len = sndbuf; - tcp_write(pcb, data, len, 0); - instance->ack_consumed(len); - } - if(close_flag) - tcp_output(pcb); - if((len < 0) || close_flag) - net_server_close(cs, pcb); - } -} - -static void net_server_err(void *arg, err_t err) -{ - struct net_server_connstate *cs; - - cs = (struct net_server_connstate *)arg; - net_server_close(cs, NULL); -} - -static err_t net_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - struct net_server_instance *instance; - struct net_server_connstate *cs; - - instance = (struct net_server_instance *)arg; - cs = cs_new(instance); - if(!cs) - return ERR_MEM; - tcp_accepted(instance->listen_pcb); - tcp_arg(newpcb, cs); - tcp_recv(newpcb, net_server_recv); - tcp_err(newpcb, net_server_err); - return ERR_OK; -} - -void net_server_init(struct net_server_instance *instance) -{ - struct tcp_pcb *bind_pcb; - - bind_pcb = tcp_new(); - bind_pcb->so_options |= SOF_KEEPALIVE; - tcp_bind(bind_pcb, IP_ADDR_ANY, instance->port); - - instance->listen_pcb = tcp_listen(bind_pcb); - tcp_arg(instance->listen_pcb, instance); - tcp_accept(instance->listen_pcb, net_server_accept); -} - -extern struct tcp_pcb *tcp_active_pcbs; - -void net_server_service(void) -{ - struct tcp_pcb *pcb; - - pcb = tcp_active_pcbs; - while(pcb) { - if(pcb->recv == net_server_recv) /* filter our connections */ - tcp_pcb_service(pcb->callback_arg, pcb); - pcb = pcb->next; - } -} diff --git a/artiq/runtime/net_server.h b/artiq/runtime/net_server.h deleted file mode 100644 index 9bb57d6c6..000000000 --- a/artiq/runtime/net_server.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __NET_SERVER_H -#define __NET_SERVER_H - -struct net_server_connstate; -struct tcp_pcb; - -struct net_server_instance { - int port; - - void (*start)(void); - void (*end)(void); - int (*input)(void *data, int length); - void (*poll)(void **data, int *length, int *close_flag); - void (*ack_consumed)(int length); - void (*ack_sent)(int length); - - /* internal use */ - struct tcp_pcb *listen_pcb; - struct net_server_connstate *open_session_cs; - struct tcp_pcb *open_session_pcb; -}; - -void net_server_init(struct net_server_instance *instance); -void net_server_service(void); - -#endif /* __NET_SERVER_H */ diff --git a/artiq/runtime/rtiocrg.c b/artiq/runtime/rtiocrg.c deleted file mode 100644 index 2851cc994..000000000 --- a/artiq/runtime/rtiocrg.c +++ /dev/null @@ -1,71 +0,0 @@ -#include - -#include "log.h" -#include "clock.h" -#include "flash_storage.h" -#include "rtiocrg.h" - -void rtiocrg_init(void) -{ - char b; - int clk; - -#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR - rtio_crg_pll_reset_write(0); -#endif - b = 'i'; - clk = 0; - fs_read("startup_clock", &b, 1, NULL); - if(b == 'i') - core_log("Startup RTIO clock: internal\n"); - else if(b == 'e') { - core_log("Startup RTIO clock: external\n"); - clk = 1; - } else - core_log("ERROR: unrecognized startup_clock entry in flash storage\n"); - - if(!rtiocrg_switch_clock(clk)) { - core_log("ERROR: startup RTIO clock failed\n"); - core_log("WARNING: this may cause the system initialization to fail\n"); - core_log("WARNING: fix clocking and reset the device\n"); - } -} - -int rtiocrg_check(void) -{ -#if ((defined CSR_RTIO_CRG_BASE) && (defined CSR_RTIO_CRG_PLL_RESET_ADDR)) - return rtio_crg_pll_locked_read(); -#else - return 1; -#endif -} - -int rtiocrg_switch_clock(int clk) -{ -#ifdef CSR_RTIO_CRG_BASE - int current_clk; - - current_clk = rtio_crg_clock_sel_read(); - if(clk == current_clk) { -#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR - busywait_us(150); - if(!rtio_crg_pll_locked_read()) - return 0; -#endif - return 1; - } -#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR - rtio_crg_pll_reset_write(1); -#endif - rtio_crg_clock_sel_write(clk); -#ifdef CSR_RTIO_CRG_PLL_RESET_ADDR - rtio_crg_pll_reset_write(0); - busywait_us(150); - if(!rtio_crg_pll_locked_read()) - return 0; -#endif - return 1; -#else /* CSR_RTIO_CRG_BASE */ - return 1; -#endif -} diff --git a/artiq/runtime/rtiocrg.h b/artiq/runtime/rtiocrg.h deleted file mode 100644 index df498f617..000000000 --- a/artiq/runtime/rtiocrg.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __RTIOCRG_H -#define __RTIOCRG_H - -void rtiocrg_init(void); -int rtiocrg_check(void); -int rtiocrg_switch_clock(int clk); - -#endif /* __RTIOCRG_H */ diff --git a/artiq/runtime/session.c b/artiq/runtime/session.c deleted file mode 100644 index 054d808e1..000000000 --- a/artiq/runtime/session.c +++ /dev/null @@ -1,1136 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "mailbox.h" -#include "messages.h" - -#include "clock.h" -#include "log.h" -#include "kloader.h" -#include "artiq_personality.h" -#include "flash_storage.h" -#include "rtiocrg.h" -#include "session.h" - -// 2.5MiB in payload + 1KiB for headers. -// We need more than 1MiB to send a 1MiB list due to tags; -// about 5/4MiB for an 1MiB int32 list, 9/8MiB for an 1MiB int64 list. -#define BUFFER_SIZE (2560*1024 + 1024) -#define BUFFER_IN_SIZE BUFFER_SIZE -#define BUFFER_OUT_SIZE BUFFER_SIZE - -static int process_input(); -static int out_packet_available(); - -// ============================= Reader interface ============================= - -// Align the 9th byte (right after the header) of buffer_in so that -// the payload can be deserialized directly from the buffer using word reads. -static struct { - char padding[3]; - union { - char data[BUFFER_IN_SIZE]; - struct { - int32_t sync; - int32_t length; - int8_t type; - } __attribute__((packed)) header; - }; -} __attribute__((packed, aligned(4))) buffer_in; - -static int buffer_in_write_cursor, buffer_in_read_cursor; - -static void in_packet_reset() -{ - buffer_in_write_cursor = 0; - buffer_in_read_cursor = 0; -} - -static int in_packet_fill(uint8_t *data, int length) -{ - int consumed = 0; - while(consumed < length) { - /* Make sure the output buffer is available for any reply - * we might need to send. */ - if(!out_packet_available()) - break; - - if(buffer_in_write_cursor < 4) { - /* Haven't received the synchronization sequence yet. */ - buffer_in.data[buffer_in_write_cursor++] = data[consumed]; - - /* Framing error? */ - if(data[consumed++] != 0x5a) { - buffer_in_write_cursor = 0; - continue; - } - } else if(buffer_in_write_cursor < 8) { - /* Haven't received the packet length yet. */ - buffer_in.data[buffer_in_write_cursor++] = data[consumed++]; - } else if(buffer_in.header.length == 0) { - /* Zero-length packet means session reset. */ - return -2; - } else if(buffer_in.header.length > BUFFER_IN_SIZE) { - /* Packet wouldn't fit in the buffer. */ - return -1; - } else if(buffer_in.header.length > buffer_in_write_cursor) { - /* Receiving payload. */ - int remaining = buffer_in.header.length - buffer_in_write_cursor; - int amount = length - consumed > remaining ? remaining : length - consumed; - memcpy(&buffer_in.data[buffer_in_write_cursor], &data[consumed], - amount); - buffer_in_write_cursor += amount; - consumed += amount; - } - - if(buffer_in.header.length == buffer_in_write_cursor) { - /* We have a complete packet. */ - - buffer_in_read_cursor = sizeof(buffer_in.header); - if(!process_input()) - return -1; - - if(buffer_in_read_cursor < buffer_in_write_cursor) { - core_log("session.c: read underrun (%d bytes remaining)\n", - buffer_in_write_cursor - buffer_in_read_cursor); - } - - in_packet_reset(); - } - } - - return consumed; -} - -static void in_packet_chunk(void *ptr, int length) -{ - if(buffer_in_read_cursor + length > buffer_in_write_cursor) { - core_log("session.c: read overrun while trying to read %d bytes" - " (%d remaining)\n", - length, buffer_in_write_cursor - buffer_in_read_cursor); - } - - if(ptr != NULL) - memcpy(ptr, &buffer_in.data[buffer_in_read_cursor], length); - buffer_in_read_cursor += length; -} - -static int8_t in_packet_int8() -{ - int8_t result; - in_packet_chunk(&result, sizeof(result)); - return result; -} - -static int32_t in_packet_int32() -{ - int32_t result; - in_packet_chunk(&result, sizeof(result)); - return result; -} - -static int64_t in_packet_int64() -{ - int64_t result; - in_packet_chunk(&result, sizeof(result)); - return result; -} - -static const void *in_packet_bytes(int *length) -{ - *length = in_packet_int32(); - const void *ptr = &buffer_in.data[buffer_in_read_cursor]; - in_packet_chunk(NULL, *length); - return ptr; -} - -static const char *in_packet_string() -{ - int length; - const char *string = in_packet_bytes(&length); - if(string[length - 1] != 0) { - core_log("session.c: string is not zero-terminated\n"); - return ""; - } - return string; -} - -// ============================= Writer interface ============================= - -static union { - char data[BUFFER_OUT_SIZE]; - struct { - int32_t sync; - int32_t length; - int8_t type; - } __attribute__((packed)) header; -} buffer_out; - -static int buffer_out_read_cursor, buffer_out_sent_cursor, buffer_out_write_cursor; - -static void out_packet_reset() -{ - buffer_out_read_cursor = 0; - buffer_out_write_cursor = 0; - buffer_out_sent_cursor = 0; -} - -static int out_packet_available() -{ - return buffer_out_write_cursor == 0; -} - -static void out_packet_extract(void **data, int *length) -{ - if(buffer_out_write_cursor > 0 && - buffer_out.header.length > 0) { - *data = &buffer_out.data[buffer_out_read_cursor]; - *length = buffer_out_write_cursor - buffer_out_read_cursor; - } else { - *length = 0; - } -} - -static void out_packet_advance_consumed(int length) -{ - if(buffer_out_read_cursor + length > buffer_out_write_cursor) { - core_log("session.c: write underrun (consume) while trying to" - " acknowledge %d bytes (%d remaining)\n", - length, buffer_out_write_cursor - buffer_out_read_cursor); - return; - } - - buffer_out_read_cursor += length; -} - -static void out_packet_advance_sent(int length) -{ - if(buffer_out_sent_cursor + length > buffer_out_write_cursor) { - core_log("session.c: write underrun (send) while trying to" - " acknowledge %d bytes (%d remaining)\n", - length, buffer_out_write_cursor - buffer_out_sent_cursor); - return; - } - - buffer_out_sent_cursor += length; - if(buffer_out_sent_cursor == buffer_out_write_cursor) - out_packet_reset(); -} - -static int out_packet_chunk(const void *ptr, int length) -{ - if(buffer_out_write_cursor + length > BUFFER_OUT_SIZE) { - core_log("session.c: write overrun while trying to write %d bytes" - " (%d remaining)\n", - length, BUFFER_OUT_SIZE - buffer_out_write_cursor); - return 0; - } - - memcpy(&buffer_out.data[buffer_out_write_cursor], ptr, length); - buffer_out_write_cursor += length; - return 1; -} - -static void out_packet_start(int type) -{ - buffer_out.header.sync = 0x5a5a5a5a; - buffer_out.header.type = type; - buffer_out.header.length = 0; - buffer_out_write_cursor = sizeof(buffer_out.header); -} - -static void out_packet_finish() -{ - buffer_out.header.length = buffer_out_write_cursor; -} - -static void out_packet_empty(int type) -{ - out_packet_start(type); - out_packet_finish(); -} - -static int out_packet_int8(int8_t value) -{ - return out_packet_chunk(&value, sizeof(value)); -} - -static int out_packet_int32(int32_t value) -{ - return out_packet_chunk(&value, sizeof(value)); -} - -static int out_packet_int64(int64_t value) -{ - return out_packet_chunk(&value, sizeof(value)); -} - -static int out_packet_float64(double value) -{ - return out_packet_chunk(&value, sizeof(value)); -} - -static int out_packet_bytes(const void *ptr, int length) -{ - return out_packet_int32(length) && - out_packet_chunk(ptr, length); -} - -static int out_packet_string(const char *string) -{ - return out_packet_bytes(string, strlen(string) + 1); -} - -// =============================== API handling =============================== - -static int user_kernel_state; - -enum { - USER_KERNEL_NONE = 0, - USER_KERNEL_LOADED, - USER_KERNEL_RUNNING, - USER_KERNEL_WAIT_RPC /* < must come after _RUNNING */ -}; - -void session_startup_kernel(void) -{ - struct msg_base *umsg; - - watchdog_init(); - if(!kloader_start_startup_kernel()) - return; - - core_log("Startup kernel started\n"); - while(1) { - kloader_service_essential_kmsg(); - - umsg = mailbox_receive(); - if(umsg) { - if(!kloader_validate_kpointer(umsg)) - break; - if(kloader_is_essential_kmsg(umsg->type)) - continue; - if(umsg->type == MESSAGE_TYPE_FINISHED) - break; - else if(umsg->type == MESSAGE_TYPE_EXCEPTION) { - core_log("WARNING: startup kernel ended with exception\n"); - break; - } else { - core_log("ERROR: received invalid message type from kernel CPU\n"); - break; - } - } - - if(watchdog_expired()) { - core_log("WARNING: watchdog expired in startup kernel\n"); - break; - } - } - kloader_stop(); - core_log("Startup kernel terminated\n"); -} - -void session_start(void) -{ - in_packet_reset(); - out_packet_reset(); - - kloader_stop(); - user_kernel_state = USER_KERNEL_NONE; -} - -void session_end(void) -{ - kloader_stop(); - watchdog_init(); - kloader_start_idle_kernel(); -} - -/* host to device */ -enum { - REMOTEMSG_TYPE_LOG_REQUEST = 1, - REMOTEMSG_TYPE_LOG_CLEAR, - - REMOTEMSG_TYPE_IDENT_REQUEST, - REMOTEMSG_TYPE_SWITCH_CLOCK, - - REMOTEMSG_TYPE_LOAD_LIBRARY, - REMOTEMSG_TYPE_RUN_KERNEL, - - REMOTEMSG_TYPE_RPC_REPLY, - REMOTEMSG_TYPE_RPC_EXCEPTION, - - REMOTEMSG_TYPE_FLASH_READ_REQUEST, - REMOTEMSG_TYPE_FLASH_WRITE_REQUEST, - REMOTEMSG_TYPE_FLASH_ERASE_REQUEST, - REMOTEMSG_TYPE_FLASH_REMOVE_REQUEST -}; - -/* device to host */ -enum { - REMOTEMSG_TYPE_LOG_REPLY = 1, - - REMOTEMSG_TYPE_IDENT_REPLY, - REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED, - REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED, - - REMOTEMSG_TYPE_LOAD_COMPLETED, - REMOTEMSG_TYPE_LOAD_FAILED, - - REMOTEMSG_TYPE_KERNEL_FINISHED, - REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED, - REMOTEMSG_TYPE_KERNEL_EXCEPTION, - - REMOTEMSG_TYPE_RPC_REQUEST, - - REMOTEMSG_TYPE_FLASH_READ_REPLY, - REMOTEMSG_TYPE_FLASH_OK_REPLY, - REMOTEMSG_TYPE_FLASH_ERROR_REPLY, - - REMOTEMSG_TYPE_WATCHDOG_EXPIRED, - REMOTEMSG_TYPE_CLOCK_FAILURE, -}; - -static int receive_rpc_value(const char **tag, void **slot); - -static int process_input(void) -{ - switch(buffer_in.header.type) { - case REMOTEMSG_TYPE_IDENT_REQUEST: { - char version[IDENT_SIZE]; - - get_ident(version); - - out_packet_start(REMOTEMSG_TYPE_IDENT_REPLY); - out_packet_chunk("AROR", 4); - out_packet_chunk(version, strlen(version)); - out_packet_finish(); - break; - } - - case REMOTEMSG_TYPE_SWITCH_CLOCK: { - int clk = in_packet_int8(); - - if(user_kernel_state >= USER_KERNEL_RUNNING) { - core_log("Attempted to switch RTIO clock while kernel running\n"); - out_packet_empty(REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED); - break; - } - - if(rtiocrg_switch_clock(clk)) - out_packet_empty(REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED); - else - out_packet_empty(REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED); - break; - } - - case REMOTEMSG_TYPE_LOG_REQUEST: -#if (LOG_BUFFER_SIZE + 9) > BUFFER_OUT_SIZE -#error Output buffer cannot hold the log buffer -#endif - out_packet_start(REMOTEMSG_TYPE_LOG_REPLY); - core_log_get(&buffer_out.data[buffer_out_write_cursor]); - buffer_out_write_cursor += LOG_BUFFER_SIZE; - out_packet_finish(); - break; - - case REMOTEMSG_TYPE_LOG_CLEAR: - core_log_clear(); - out_packet_empty(REMOTEMSG_TYPE_LOG_REPLY); - break; - - case REMOTEMSG_TYPE_FLASH_READ_REQUEST: { -#if CONFIG_SPIFLASH_SECTOR_SIZE - 4 > BUFFER_OUT_SIZE - 9 -#error Output buffer cannot hold the flash storage data -#endif - const char *key = in_packet_string(); - int value_length; - - out_packet_start(REMOTEMSG_TYPE_FLASH_READ_REPLY); - value_length = fs_read(key, &buffer_out.data[buffer_out_write_cursor], - sizeof(buffer_out.data) - buffer_out_write_cursor, NULL); - buffer_out_write_cursor += value_length; - out_packet_finish(); - break; - } - - case REMOTEMSG_TYPE_FLASH_WRITE_REQUEST: { -#if CONFIG_SPIFLASH_SECTOR_SIZE - 4 > BUFFER_IN_SIZE - 9 -#error Input buffer cannot hold the flash storage data -#endif - const char *key, *value; - int value_length; - key = in_packet_string(); - value = in_packet_bytes(&value_length); - - if(fs_write(key, value, value_length)) - out_packet_empty(REMOTEMSG_TYPE_FLASH_OK_REPLY); - else - out_packet_empty(REMOTEMSG_TYPE_FLASH_ERROR_REPLY); - break; - } - - case REMOTEMSG_TYPE_FLASH_ERASE_REQUEST: - fs_erase(); - out_packet_empty(REMOTEMSG_TYPE_FLASH_OK_REPLY); - break; - - case REMOTEMSG_TYPE_FLASH_REMOVE_REQUEST: { - const char *key = in_packet_string(); - - fs_remove(key); - out_packet_empty(REMOTEMSG_TYPE_FLASH_OK_REPLY); - break; - } - - case REMOTEMSG_TYPE_LOAD_LIBRARY: { - const void *kernel = &buffer_in.data[buffer_in_read_cursor]; - buffer_in_read_cursor = buffer_in_write_cursor; - - if(user_kernel_state >= USER_KERNEL_RUNNING) { - core_log("Attempted to load new kernel library while already running\n"); - out_packet_empty(REMOTEMSG_TYPE_LOAD_FAILED); - break; - } - - if(kloader_load_library(kernel)) { - out_packet_empty(REMOTEMSG_TYPE_LOAD_COMPLETED); - user_kernel_state = USER_KERNEL_LOADED; - } else { - out_packet_empty(REMOTEMSG_TYPE_LOAD_FAILED); - } - break; - } - - case REMOTEMSG_TYPE_RUN_KERNEL: - if(user_kernel_state != USER_KERNEL_LOADED) { - core_log("Attempted to run kernel while not in the LOADED state\n"); - out_packet_empty(REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED); - break; - } - - watchdog_init(); - kloader_start_kernel(); - - user_kernel_state = USER_KERNEL_RUNNING; - break; - - case REMOTEMSG_TYPE_RPC_REPLY: { - struct msg_rpc_recv_request *request; - struct msg_rpc_recv_reply reply; - - if(user_kernel_state != USER_KERNEL_WAIT_RPC) { - core_log("Unsolicited RPC reply\n"); - return 0; // restart session - } - - request = mailbox_wait_and_receive(); - if(request->type != MESSAGE_TYPE_RPC_RECV_REQUEST) { - core_log("Expected MESSAGE_TYPE_RPC_RECV_REQUEST, got %d\n", - request->type); - return 0; // restart session - } - - const char *tag = in_packet_string(); - void *slot = request->slot; - if(!receive_rpc_value(&tag, &slot)) { - core_log("Failed to receive RPC reply\n"); - return 0; // restart session - } - - reply.type = MESSAGE_TYPE_RPC_RECV_REPLY; - reply.alloc_size = 0; - reply.exception = NULL; - mailbox_send_and_wait(&reply); - - user_kernel_state = USER_KERNEL_RUNNING; - break; - } - - case REMOTEMSG_TYPE_RPC_EXCEPTION: { - struct msg_rpc_recv_request *request; - struct msg_rpc_recv_reply reply; - - struct artiq_exception exception; - exception.name = in_packet_string(); - exception.message = in_packet_string(); - exception.param[0] = in_packet_int64(); - exception.param[1] = in_packet_int64(); - exception.param[2] = in_packet_int64(); - exception.file = in_packet_string(); - exception.line = in_packet_int32(); - exception.column = in_packet_int32(); - exception.function = in_packet_string(); - - if(user_kernel_state != USER_KERNEL_WAIT_RPC) { - core_log("Unsolicited RPC exception reply\n"); - return 0; // restart session - } - - request = mailbox_wait_and_receive(); - if(request->type != MESSAGE_TYPE_RPC_RECV_REQUEST) { - core_log("Expected MESSAGE_TYPE_RPC_RECV_REQUEST, got %d\n", - request->type); - return 0; // restart session - } - - reply.type = MESSAGE_TYPE_RPC_RECV_REPLY; - reply.alloc_size = 0; - reply.exception = &exception; - mailbox_send_and_wait(&reply); - - user_kernel_state = USER_KERNEL_RUNNING; - break; - } - - default: - core_log("Received invalid packet type %d from host\n", - buffer_in.header.type); - return 0; - } - - return 1; -} - -// See comm_generic.py:_{send,receive}_rpc_value and llvm_ir_generator.py:_rpc_tag. -static void skip_rpc_value(const char **tag) { - switch(*(*tag)++) { - case 't': { - int size = *(*tag)++; - for(int i = 0; i < size; i++) - skip_rpc_value(tag); - break; - } - - case 'l': - case 'a': - skip_rpc_value(tag); - break; - - case 'r': - skip_rpc_value(tag); - break; - } -} - -static int sizeof_rpc_value(const char **tag) -{ - switch(*(*tag)++) { - case 't': { // tuple - int size = *(*tag)++; - - int32_t length = 0; - for(int i = 0; i < size; i++) - length += sizeof_rpc_value(tag); - return length; - } - - case 'n': // None - return 0; - - case 'b': // bool - return sizeof(int8_t); - - case 'i': // int(width=32) - return sizeof(int32_t); - - case 'I': // int(width=64) - return sizeof(int64_t); - - case 'f': // float - return sizeof(double); - - case 'F': // Fraction - return sizeof(struct { int64_t numerator, denominator; }); - - case 's': // string - return sizeof(char *); - - case 'l': // list(elt='a) - case 'a': // array(elt='a) - skip_rpc_value(tag); - return sizeof(struct { int32_t length; struct {} *elements; }); - - case 'r': // range(elt='a) - return sizeof_rpc_value(tag) * 3; - - default: - core_log("sizeof_rpc_value: unknown tag %02x\n", *((*tag) - 1)); - return 0; - } -} - -static void *alloc_rpc_value(int size) -{ - struct msg_rpc_recv_request *request; - struct msg_rpc_recv_reply reply; - - reply.type = MESSAGE_TYPE_RPC_RECV_REPLY; - reply.alloc_size = size; - reply.exception = NULL; - mailbox_send_and_wait(&reply); - - request = mailbox_wait_and_receive(); - if(request->type != MESSAGE_TYPE_RPC_RECV_REQUEST) { - core_log("Expected MESSAGE_TYPE_RPC_RECV_REQUEST, got %d\n", - request->type); - return NULL; - } - return request->slot; -} - -static int receive_rpc_value(const char **tag, void **slot) -{ - switch(*(*tag)++) { - case 't': { // tuple - int size = *(*tag)++; - - for(int i = 0; i < size; i++) { - if(!receive_rpc_value(tag, slot)) - return 0; - } - break; - } - - case 'n': // None - break; - - case 'b': { // bool - *((*(int8_t**)slot)++) = in_packet_int8(); - break; - } - - case 'i': { // int(width=32) - *((*(int32_t**)slot)++) = in_packet_int32(); - break; - } - - case 'I': { // int(width=64) - *((*(int64_t**)slot)++) = in_packet_int64(); - break; - } - - case 'f': { // float - *((*(int64_t**)slot)++) = in_packet_int64(); - break; - } - - case 'F': { // Fraction - struct { int64_t numerator, denominator; } *fraction = *slot; - fraction->numerator = in_packet_int64(); - fraction->denominator = in_packet_int64(); - *slot = (void*)((intptr_t)(*slot) + sizeof(*fraction)); - break; - } - - case 's': { // string - const char *in_string = in_packet_string(); - char *out_string = alloc_rpc_value(strlen(in_string) + 1); - memcpy(out_string, in_string, strlen(in_string) + 1); - *((*(char***)slot)++) = out_string; - break; - } - - case 'l': // list(elt='a) - case 'a': { // array(elt='a) - struct { int32_t length; struct {} *elements; } *list = *slot; - list->length = in_packet_int32(); - - const char *tag_copy = *tag; - list->elements = alloc_rpc_value(sizeof_rpc_value(&tag_copy) * list->length); - - void *element = list->elements; - for(int i = 0; i < list->length; i++) { - const char *tag_copy = *tag; - if(!receive_rpc_value(&tag_copy, &element)) - return 0; - } - skip_rpc_value(tag); - break; - } - - case 'r': { // range(elt='a) - const char *tag_copy; - tag_copy = *tag; - if(!receive_rpc_value(&tag_copy, slot)) // min - return 0; - tag_copy = *tag; - if(!receive_rpc_value(&tag_copy, slot)) // max - return 0; - tag_copy = *tag; - if(!receive_rpc_value(&tag_copy, slot)) // step - return 0; - *tag = tag_copy; - break; - } - - default: - core_log("receive_rpc_value: unknown tag %02x\n", *((*tag) - 1)); - return 0; - } - - return 1; -} - -static int send_rpc_value(const char **tag, void **value) -{ - if(!out_packet_int8(**tag)) - return 0; - - switch(*(*tag)++) { - case 't': { // tuple - int size = *(*tag)++; - if(!out_packet_int8(size)) - return 0; - - for(int i = 0; i < size; i++) { - if(!send_rpc_value(tag, value)) - return 0; - } - break; - } - - case 'n': // None - break; - - case 'b': { // bool - return out_packet_int8(*((*(int8_t**)value)++)); - } - - case 'i': { // int(width=32) - return out_packet_int32(*((*(int32_t**)value)++)); - } - - case 'I': { // int(width=64) - return out_packet_int64(*((*(int64_t**)value)++)); - } - - case 'f': { // float - return out_packet_float64(*((*(double**)value)++)); - } - - case 'F': { // Fraction - struct { int64_t numerator, denominator; } *fraction = *value; - if(!out_packet_int64(fraction->numerator)) - return 0; - if(!out_packet_int64(fraction->denominator)) - return 0; - *value = (void*)((intptr_t)(*value) + sizeof(*fraction)); - break; - } - - case 's': { // string - return out_packet_string(*((*(const char***)value)++)); - } - - case 'l': // list(elt='a) - case 'a': { // array(elt='a) - struct { uint32_t length; struct {} *elements; } *list = *value; - void *element = list->elements; - - if(!out_packet_int32(list->length)) - return 0; - - for(int i = 0; i < list->length; i++) { - const char *tag_copy = *tag; - if(!send_rpc_value(&tag_copy, &element)) { - core_log("failed to send list at element %d/%d\n", i, list->length); - return 0; - } - } - skip_rpc_value(tag); - - *value = (void*)((intptr_t)(*value) + sizeof(*list)); - break; - } - - case 'r': { // range(elt='a) - const char *tag_copy; - tag_copy = *tag; - if(!send_rpc_value(&tag_copy, value)) // min - return 0; - tag_copy = *tag; - if(!send_rpc_value(&tag_copy, value)) // max - return 0; - tag_copy = *tag; - if(!send_rpc_value(&tag_copy, value)) // step - return 0; - *tag = tag_copy; - break; - } - - case 'k': { // keyword(value='a) - struct { const char *name; struct {} contents; } *option = *value; - void *contents = &option->contents; - - if(!out_packet_string(option->name)) - return 0; - - // keyword never appears in composite types, so we don't have - // to accurately advance *value. - return send_rpc_value(tag, &contents); - } - - case 'O': { // host object - struct { uint32_t id; } **object = *value; - - if(!out_packet_int32((*object)->id)) - return 0; - - *value = (void*)((intptr_t)(*value) + sizeof(*object)); - break; - } - - default: - core_log("send_rpc_value: unknown tag %02x\n", *((*tag) - 1)); - return 0; - } - - return 1; -} - -static int send_rpc_request(int service, const char *tag, void **data) -{ - out_packet_start(REMOTEMSG_TYPE_RPC_REQUEST); - out_packet_int32(service); - - while(*tag != ':') { - void *value = *data++; - if(!kloader_validate_kpointer(value)) - return 0; - if(!send_rpc_value(&tag, &value)) - return 0; - } - out_packet_int8(0); - - out_packet_string(tag + 1); // return tags - out_packet_finish(); - return 1; -} - -struct cache_row { - struct cache_row *next; - char *key; - size_t length; - int32_t *elements; - int borrowed; -}; - -static struct cache_row *cache; - -/* assumes output buffer is empty when called */ -static int process_kmsg(struct msg_base *umsg) -{ - if(!kloader_validate_kpointer(umsg)) - return 0; - if(kloader_is_essential_kmsg(umsg->type)) - return 1; /* handled elsewhere */ - if(user_kernel_state == USER_KERNEL_LOADED && - umsg->type == MESSAGE_TYPE_LOAD_REPLY) { - // Kernel standing by. - return 1; - } - if(user_kernel_state == USER_KERNEL_WAIT_RPC && - umsg->type == MESSAGE_TYPE_RPC_RECV_REQUEST) { - // Handled and acknowledged when we receive - // REMOTEMSG_TYPE_RPC_{EXCEPTION,REPLY}. - return 1; - } - if(user_kernel_state != USER_KERNEL_RUNNING) { - core_log("Received unexpected message from kernel CPU while not in running state\n"); - return 0; - } - - switch(umsg->type) { - case MESSAGE_TYPE_FINISHED: - out_packet_empty(REMOTEMSG_TYPE_KERNEL_FINISHED); - - for(struct cache_row *iter = cache; iter; iter = iter->next) - iter->borrowed = 0; - - kloader_stop(); - user_kernel_state = USER_KERNEL_LOADED; - - break; - - case MESSAGE_TYPE_EXCEPTION: { - struct msg_exception *msg = (struct msg_exception *)umsg; - - out_packet_start(REMOTEMSG_TYPE_KERNEL_EXCEPTION); - - out_packet_string(msg->exception->name); - out_packet_string(msg->exception->message); - out_packet_int64(msg->exception->param[0]); - out_packet_int64(msg->exception->param[1]); - out_packet_int64(msg->exception->param[2]); - - out_packet_string(msg->exception->file); - out_packet_int32(msg->exception->line); - out_packet_int32(msg->exception->column); - out_packet_string(msg->exception->function); - - out_packet_int32(msg->backtrace_size); - for(int i = 0; i < msg->backtrace_size; i++) { - out_packet_int32(msg->backtrace[i]); - } - - out_packet_finish(); - - kloader_stop(); - user_kernel_state = USER_KERNEL_LOADED; - mailbox_acknowledge(); - break; - } - - case MESSAGE_TYPE_RPC_SEND: - case MESSAGE_TYPE_RPC_BATCH: { - struct msg_rpc_send *msg = (struct msg_rpc_send *)umsg; - - if(!send_rpc_request(msg->service, msg->tag, msg->data)) { - core_log("Failed to send RPC request (service %d, tag %s)\n", - msg->service, msg->tag); - return 0; // restart session - } - - if(msg->type == MESSAGE_TYPE_RPC_SEND) - user_kernel_state = USER_KERNEL_WAIT_RPC; - mailbox_acknowledge(); - break; - } - - case MESSAGE_TYPE_CACHE_GET_REQUEST: { - struct msg_cache_get_request *request = (struct msg_cache_get_request *)umsg; - struct msg_cache_get_reply reply; - - reply.type = MESSAGE_TYPE_CACHE_GET_REPLY; - reply.length = 0; - reply.elements = NULL; - - for(struct cache_row *iter = cache; iter; iter = iter->next) { - if(!strcmp(iter->key, request->key)) { - reply.length = iter->length; - reply.elements = iter->elements; - iter->borrowed = 1; - break; - } - } - - mailbox_send(&reply); - break; - } - - case MESSAGE_TYPE_CACHE_PUT_REQUEST: { - struct msg_cache_put_request *request = (struct msg_cache_put_request *)umsg; - struct msg_cache_put_reply reply; - - reply.type = MESSAGE_TYPE_CACHE_PUT_REPLY; - - struct cache_row *row = NULL; - for(struct cache_row *iter = cache; iter; iter = iter->next) { - if(!strcmp(iter->key, request->key)) { - row = iter; - break; - } - } - - if(!row) { - row = calloc(1, sizeof(struct cache_row)); - row->key = calloc(strlen(request->key) + 1, 1); - strcpy(row->key, request->key); - row->next = cache; - cache = row; - } - - if(!row->borrowed) { - row->length = request->length; - if(row->length != 0) { - row->elements = calloc(row->length, sizeof(int32_t)); - memcpy(row->elements, request->elements, - sizeof(int32_t) * row->length); - } else { - free(row->elements); - row->elements = NULL; - } - - reply.succeeded = 1; - } else { - reply.succeeded = 0; - } - - mailbox_send(&reply); - break; - } - - default: { - core_log("Received invalid message type %d from kernel CPU\n", - umsg->type); - return 0; - } - } - - return 1; -} - -/* Returns amount of bytes consumed on success. - * Returns -1 in case of irrecoverable error - * (the session must be dropped and session_end called). - * Returns -2 if the host has requested session reset. - */ -int session_input(void *data, int length) -{ - return in_packet_fill((uint8_t*)data, length); -} - -/* *length is set to -1 in case of irrecoverable error - * (the session must be dropped and session_end called) - */ -void session_poll(void **data, int *length, int *close_flag) -{ - *close_flag = 0; - - if(user_kernel_state == USER_KERNEL_RUNNING) { - if(watchdog_expired()) { - core_log("Watchdog expired\n"); - - *close_flag = 1; - out_packet_empty(REMOTEMSG_TYPE_WATCHDOG_EXPIRED); - } - if(!rtiocrg_check()) { - core_log("RTIO clock failure\n"); - - *close_flag = 1; - out_packet_empty(REMOTEMSG_TYPE_CLOCK_FAILURE); - } - } - - if(!*close_flag) { - /* If the output buffer is available, - * check if the kernel CPU has something to transmit. - */ - if(out_packet_available()) { - struct msg_base *umsg = mailbox_receive(); - if(umsg) { - if(!process_kmsg(umsg)) { - *length = -1; - return; - } - } - } - } - - out_packet_extract(data, length); -} - -void session_ack_consumed(int length) -{ - out_packet_advance_consumed(length); -} - -void session_ack_sent(int length) -{ - out_packet_advance_sent(length); -} diff --git a/artiq/runtime/session.h b/artiq/runtime/session.h deleted file mode 100644 index 06ee421ed..000000000 --- a/artiq/runtime/session.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __SESSION_H -#define __SESSION_H - -void session_startup_kernel(void); -void session_start(void); -void session_end(void); - -int session_input(void *data, int length); -void session_poll(void **data, int *length, int *close_flag); -void session_ack_consumed(int length); -void session_ack_sent(int length); - -#endif /* __SESSION_H */