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: 56c85dd2cb26
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: 4d311943431e
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on May 1, 2015

  1. Copy the full SHA
    d3753c9 View commit details
  2. Copy the full SHA
    4d31194 View commit details
Showing with 297 additions and 203 deletions.
  1. +1 −1 soc/runtime/Makefile
  2. +18 −2 soc/runtime/kloader.c
  3. +215 −0 soc/runtime/kserver.c
  4. +7 −0 soc/runtime/kserver.h
  5. +56 −200 soc/runtime/main.c
2 changes: 1 addition & 1 deletion soc/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include $(MSCDIR)/software/common.mak

OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o mailbox.o ksupport_data.o main.o
OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o mailbox.o ksupport_data.o kserver.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o dds.o

CFLAGS += -Ilwip/src/include -Iliblwip
20 changes: 18 additions & 2 deletions soc/runtime/kloader.c
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@
#include <generated/csr.h>

#include "log.h"
#include "flash_storage.h"
#include "mailbox.h"
#include "elf_loader.h"
#include "services.h"
#include "kloader.h"


static struct symbol symtab[128];
static int _symtab_count;
static char _symtab_strings[128*16];
@@ -92,11 +92,27 @@ void kloader_start_user_kernel(kernel_function k)

void kloader_start_idle_kernel(void)
{
char buffer[32*1024];
int len;
kernel_function k;

if(!kernel_cpu_reset_read()) {
log("BUG: attempted to start kernel CPU while already running (idle kernel)");
return;
}
/* TODO */
len = fs_read("idle_kernel", buffer, sizeof(buffer), NULL);
if(len <= 0)
return;
if(!kloader_load(buffer, len)) {
log("Failed to load ELF binary for idle kernel");
return;
}
k = kloader_find("run");
if(!k) {
log("Failed to find entry point for ELF kernel");
return;
}
start_kernel_cpu((void *)k);
}

void kloader_stop_kernel(void)
215 changes: 215 additions & 0 deletions soc/runtime/kserver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#include <generated/csr.h>

#ifdef CSR_ETHMAC_BASE

#include <netif/etharp.h>
#include <netif/liteethif.h>
#include <lwip/init.h>
#include <lwip/memp.h>
#include <lwip/ip4_addr.h>
#include <lwip/ip4.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/tcp.h>
#include <lwip/timers.h>

#include "session.h"
#include "kserver.h"

struct kserver_connstate {
int magic_recognized;
struct pbuf *rp;
int rp_offset;
};

static struct kserver_connstate *cs_new(void)
{
struct kserver_connstate *cs;

cs = (struct kserver_connstate *)mem_malloc(sizeof(struct kserver_connstate));
if(!cs)
return NULL;
cs->magic_recognized = 0;
cs->rp = NULL;
cs->rp_offset = 0;
return cs;
}

static void cs_free(struct kserver_connstate *cs)
{
if(cs->rp)
pbuf_free(cs->rp);
mem_free(cs);
}

static const char kserver_magic[] = "ARTIQ coredev\n";

static int magic_ok(struct kserver_connstate *cs)
{
return cs->magic_recognized >= 14;
}

static struct kserver_connstate *active_cs;
static struct tcp_pcb *active_pcb;

static void kserver_close(struct kserver_connstate *cs, struct tcp_pcb *pcb)
{
if(cs == active_cs) {
session_end();
active_cs = NULL;
active_pcb = NULL;
}

/* 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);

cs_free(cs);
tcp_close(pcb);
}

static err_t kserver_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct kserver_connstate *cs;

cs = (struct kserver_connstate *)arg;
if(p) {
if(cs->rp)
pbuf_cat(cs->rp, p);
else {
cs->rp = p;
cs->rp_offset = 0;
}
} else
kserver_close(cs, pcb);
return ERR_OK;
}

static err_t kserver_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
session_ack_mem(len);
return ERR_OK;
}

static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb)
{
struct kserver_connstate *cs;
int remaining_in_pbuf;
char *rpp;
struct pbuf *next;
int r;

cs = (struct kserver_connstate *)arg;

while(cs->rp) {
remaining_in_pbuf = cs->rp->len - cs->rp_offset;
rpp = (char *)cs->rp->payload;
while(remaining_in_pbuf > 0) {
if(cs == active_cs) {
r = session_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
kserver_close(cs, pcb);
} else {
if(rpp[cs->rp_offset] == kserver_magic[cs->magic_recognized]) {
cs->magic_recognized++;
if(magic_ok(cs)) {
if(active_cs)
kserver_close(active_cs, active_pcb);
session_start();
active_cs = cs;
active_pcb = pcb;
tcp_sent(pcb, kserver_sent);
}
} else {
kserver_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;
}
}
}

static void kserver_err(void *arg, err_t err)
{
struct kserver_connstate *cs;

cs = (struct kserver_connstate *)arg;
cs_free(cs);
}

static struct tcp_pcb *listen_pcb;

static err_t kserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
struct kserver_connstate *cs;

cs = cs_new();
if(!cs)
return ERR_MEM;
tcp_accepted(listen_pcb);
tcp_arg(newpcb, cs);
tcp_recv(newpcb, kserver_recv);
tcp_err(newpcb, kserver_err);
return ERR_OK;
}

void kserver_init(void)
{
listen_pcb = tcp_new();
tcp_bind(listen_pcb, IP_ADDR_ANY, 1381);
listen_pcb = tcp_listen(listen_pcb);
tcp_accept(listen_pcb, kserver_accept);
}

extern struct tcp_pcb *tcp_active_pcbs;

void kserver_service(void)
{
struct tcp_pcb *pcb;
void *data;
int len, sndbuf;

/* Assume all active TCP PCBs with a non-NULL arg are our connections. */
pcb = tcp_active_pcbs;
while(pcb) {
if(pcb->callback_arg)
tcp_pcb_service(pcb->callback_arg, pcb);
pcb = pcb->next;
}

if(active_cs) {
session_poll(&data, &len);
if(len > 0) {
sndbuf = tcp_sndbuf(active_pcb);
if(len > sndbuf)
len = sndbuf;
tcp_write(active_pcb, data, len, 0);
session_ack_data(len);
}
if(len < 0)
kserver_close(active_cs, active_pcb);
}
}

#endif /* CSR_ETHMAC_BASE */
7 changes: 7 additions & 0 deletions soc/runtime/kserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef __KSERVER_H
#define __KSERVER_H

void kserver_init(void);
void kserver_service(void);

#endif /* __KSERVER_H */
Loading