Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create sDDF LWIP Library #238

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions examples/echo_server/echo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright 2022, UNSW
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <stdbool.h>
#include <stdint.h>
#include <microkit.h>
#include <sddf/util/util.h>
#include <sddf/util/string.h>
#include <sddf/util/printf.h>
#include <sddf/network/lib_sddf_lwip.h>
#include <sddf/network/queue.h>
#include <sddf/network/config.h>
#include <sddf/serial/queue.h>
#include <sddf/serial/config.h>
#include <sddf/timer/client.h>
#include <sddf/timer/config.h>
#include <sddf/benchmark/sel4bench.h>
#include <sddf/benchmark/config.h>
#include "lwip/pbuf.h"

#include "echo.h"

__attribute__((__section__(".serial_client_config"))) serial_client_config_t serial_config;

__attribute__((__section__(".timer_client_config"))) timer_client_config_t timer_config;

__attribute__((__section__(".net_client_config"))) net_client_config_t net_config;

__attribute__((__section__(".benchmark_client_config"))) benchmark_client_config_t benchmark_config;

__attribute__((__section__(".lib_sddf_lwip_config"))) lib_sddf_lwip_config_t lib_sddf_lwip_config;

serial_queue_handle_t serial_tx_queue_handle;

net_queue_handle_t net_rx_handle;
net_queue_handle_t net_tx_handle;

#define LWIP_TICK_MS 100

struct pbuf *head;
struct pbuf *tail;

/**
* Netif status callback function that output's client's Microkit name and
* obtained IP address.
*
* @param ip_addr ip address of the client.
*/
void netif_status_callback(char *ip_addr)
{
sddf_printf("DHCP request finished, IP address for netif %s is: %s\n", microkit_name, ip_addr);
}

/**
* Sets a timeout for the next lwip tick.
*/
void set_timeout(void)
{
sddf_timer_set_timeout(timer_config.driver_id, LWIP_TICK_MS * NS_IN_MS);
}

/**
* Stores a pbuf to be transmitted upon available transmit buffers.
*
* @param p pbuf to be stored.
*/
net_sddf_err_t enqueue_pbufs(struct pbuf *p)
{
/* Indicate to the tx virt that we wish to be notified about free tx buffers */
net_request_signal_free(&net_tx_handle);

if (head == NULL) {
head = p;
} else {
tail->next_chain = p;
}
tail = p;

/* Increment reference count to ensure this pbuf is not freed by lwip */
pbuf_ref(p);

return SDDF_LWIP_ERR_OK;
}

void transmit(void)
{
bool reprocess = true;
while (reprocess) {
while (head != NULL && !net_queue_empty_free(&net_tx_handle)) {
net_sddf_err_t err = sddf_lwip_transmit_pbuf(head);
if (err == SDDF_LWIP_ERR_PBUF) {
sddf_dprintf("LWIP|ERROR: attempted to send a packet of size %u > BUFFER SIZE %u\n", head->tot_len,
NET_BUFFER_SIZE);
} else if (err != SDDF_LWIP_ERR_OK) {
sddf_dprintf("LWIP|ERROR: unkown error when trying to send pbuf %p\n", head);
}

struct pbuf *temp = head;
head = temp->next_chain;
if (head == NULL) {
tail = NULL;
}
pbuf_free(temp);
}

/* Only request a signal if there are more pending pbufs to send */
if (head == NULL || !net_queue_empty_free(&net_tx_handle)) {
net_cancel_signal_free(&net_tx_handle);
} else {
net_request_signal_free(&net_tx_handle);
}
reprocess = false;

if (head != NULL && !net_queue_empty_free(&net_tx_handle)) {
net_cancel_signal_free(&net_tx_handle);
reprocess = true;
}
}
}

void init(void)
{
serial_queue_init(&serial_tx_queue_handle, serial_config.tx.queue.vaddr, serial_config.tx.data.size,
serial_config.tx.data.vaddr);
serial_putchar_init(serial_config.tx.id, &serial_tx_queue_handle);

net_queue_init(&net_rx_handle, net_config.rx.free_queue.vaddr, net_config.rx.active_queue.vaddr,
net_config.rx.num_buffers);
net_queue_init(&net_tx_handle, net_config.tx.free_queue.vaddr, net_config.tx.active_queue.vaddr,
net_config.tx.num_buffers);
net_buffers_init(&net_tx_handle, 0);

sddf_lwip_init(&lib_sddf_lwip_config, &net_config, &timer_config, net_rx_handle, net_tx_handle, NULL,
netif_status_callback, enqueue_pbufs);
set_timeout();

setup_udp_socket();
setup_utilization_socket(benchmark_config.cycle_counters, benchmark_config.start_ch, benchmark_config.stop_ch);
setup_tcp_socket();

sddf_lwip_maybe_notify();
}

void notified(microkit_channel ch)
{
if (ch == net_config.rx.id) {
sddf_lwip_process_rx();
} else if (ch == net_config.tx.id) {
transmit();
} else if (ch == timer_config.driver_id) {
sddf_lwip_process_timeout();
set_timeout();
} else if (ch == serial_config.tx.id) {
// Nothing to do
} else {
sddf_dprintf("LWIP|LOG: received notification on unexpected channel: %u\n", ch);
}

sddf_lwip_maybe_notify();
}
3 changes: 0 additions & 3 deletions examples/echo_server/echo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
#define UTILIZATION_PORT 1236
#define TCP_ECHO_PORT 1237

#define LINK_SPEED 1000000000 // Gigabit
#define ETHER_MTU 1500

int setup_udp_socket(void);
int setup_utilization_socket(void *cycle_counters, microkit_channel start_ch, microkit_channel stop_ch);
int setup_tcp_socket(void);
49 changes: 20 additions & 29 deletions examples/echo_server/echo.mk
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ METAPROGRAM := $(TOP)/meta.py

vpath %.c ${SDDF} ${ECHO_SERVER}

IMAGES := eth_driver.elf lwip0.elf lwip1.elf benchmark.elf idle.elf network_virt_rx.elf\
network_virt_tx.elf network_copy.elf timer_driver.elf uart_driver.elf serial_virt_tx.elf
IMAGES := eth_driver.elf echo0.elf echo1.elf benchmark.elf idle.elf network_virt_rx.elf\
network_virt_tx.elf network_copy0.elf network_copy1.elf timer_driver.elf\
uart_driver.elf serial_virt_tx.elf

CFLAGS := -mcpu=$(CPU) \
-mstrict-align \
Expand All @@ -51,7 +52,7 @@ CFLAGS := -mcpu=$(CPU) \
LDFLAGS := -L$(BOARD_DIR)/lib -L${LIBC}
LIBS := --start-group -lmicrokit -Tmicrokit.ld -lc libsddf_util_debug.a --end-group

CHECK_FLAGS_BOARD_MD5:=.board_cflags-$(shell echo -- ${CFLAGS} ${BOARD} ${MICROKIT_CONFIG} | shasum | sed 's/ *-//')
CHECK_FLAGS_BOARD_MD5 := .board_cflags-$(shell echo -- ${CFLAGS} ${BOARD} ${MICROKIT_CONFIG} | shasum | sed 's/ *-//')

${CHECK_FLAGS_BOARD_MD5}:
-rm -f .board_cflags-*
Expand All @@ -60,32 +61,19 @@ ${CHECK_FLAGS_BOARD_MD5}:
%.elf: %.o
$(LD) $(LDFLAGS) $< $(LIBS) -o $@

include ${SDDF}/${LWIPDIR}/Filelists.mk

# NETIFFILES: Files implementing various generic network interface functions
# Override version in Filelists.mk
NETIFFILES:=$(LWIPDIR)/netif/ethernet.c

# LWIPFILES: All the above.
LWIPFILES=lwip.c $(COREFILES) $(CORE4FILES) $(NETIFFILES)
LWIP_OBJS := $(LWIPFILES:.c=.o) lwip.o utilization_socket.o \
ECHO_OBJS := echo.o utilization_socket.o \
udp_echo_socket.o tcp_echo_socket.o

OBJS := $(LWIP_OBJS)
DEPS := $(filter %.d,$(OBJS:.o=.d))
DEPS := $(ECHO_OBJS:.o=.d)

all: loader.img

${LWIP_OBJS}: ${CHECK_FLAGS_BOARD_MD5}
lwip0.elf: $(LWIP_OBJS) libsddf_util.a
$(LD) $(LDFLAGS) $^ $(LIBS) -o $@
lwip1.elf: $(LWIP_OBJS) libsddf_util.a
${ECHO_OBJS}: ${CHECK_FLAGS_BOARD_MD5}
echo0.elf echo1.elf: $(ECHO_OBJS) libsddf_util.a lib_sddf_lwip_echo.a
$(LD) $(LDFLAGS) $^ $(LIBS) -o $@
Courtney3141 marked this conversation as resolved.
Show resolved Hide resolved

LWIPDIRS := $(addprefix ${LWIPDIR}/, core/ipv4 netif api)
${LWIP_OBJS}: |${BUILD_DIR}/${LWIPDIRS}
${BUILD_DIR}/${LWIPDIRS}:
mkdir -p $@
network_copy0.elf network_copy1.elf: network_copy.elf
cp $< $@

# Need to build libsddf_util_debug.a because it's included in LIBS
# for the unimplemented libc dependencies
Expand All @@ -106,23 +94,26 @@ $(SYSTEM_FILE): $(METAPROGRAM) $(IMAGES) $(DTB)
$(OBJCOPY) --update-section .net_copy_config=net_copy_client0_net_copier.data network_copy.elf network_copy0.elf
$(OBJCOPY) --update-section .net_copy_config=net_copy_client1_net_copier.data network_copy.elf network_copy1.elf
$(OBJCOPY) --update-section .device_resources=timer_driver_device_resources.data timer_driver.elf
$(OBJCOPY) --update-section .timer_client_config=timer_client_client0.data lwip0.elf
$(OBJCOPY) --update-section .net_client_config=net_client_client0.data lwip0.elf
$(OBJCOPY) --update-section .serial_client_config=serial_client_client0.data lwip0.elf
$(OBJCOPY) --update-section .timer_client_config=timer_client_client1.data lwip1.elf
$(OBJCOPY) --update-section .net_client_config=net_client_client1.data lwip1.elf
$(OBJCOPY) --update-section .serial_client_config=serial_client_client1.data lwip1.elf
$(OBJCOPY) --update-section .timer_client_config=timer_client_client0.data echo0.elf
$(OBJCOPY) --update-section .net_client_config=net_client_client0.data echo0.elf
$(OBJCOPY) --update-section .serial_client_config=serial_client_client0.data echo0.elf
$(OBJCOPY) --update-section .timer_client_config=timer_client_client1.data echo1.elf
$(OBJCOPY) --update-section .net_client_config=net_client_client1.data echo1.elf
$(OBJCOPY) --update-section .serial_client_config=serial_client_client1.data echo1.elf
$(OBJCOPY) --update-section .serial_client_config=serial_client_bench.data benchmark.elf
$(OBJCOPY) --update-section .benchmark_config=benchmark_config.data benchmark.elf
$(OBJCOPY) --update-section .benchmark_client_config=benchmark_client_config.data lwip0.elf
$(OBJCOPY) --update-section .benchmark_client_config=benchmark_client_config.data echo0.elf
$(OBJCOPY) --update-section .benchmark_config=benchmark_idle_config.data idle.elf
$(OBJCOPY) --update-section .lib_sddf_lwip_config=lib_sddf_lwip_config_client0.data echo0.elf
$(OBJCOPY) --update-section .lib_sddf_lwip_config=lib_sddf_lwip_config_client1.data echo1.elf

${IMAGE_FILE} $(REPORT_FILE): $(IMAGES) $(SYSTEM_FILE)
$(MICROKIT_TOOL) $(SYSTEM_FILE) --search-path $(BUILD_DIR) --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE)


include ${SDDF}/util/util.mk
include ${SDDF}/network/components/network_components.mk
include ${SDDF}/network/lib_sddf_lwip/lib_sddf_lwip.mk
include ${ETHERNET_DRIVER}/eth_driver.mk
include ${BENCHMARK}/benchmark.mk
include ${TIMER_DRIVER}/timer_driver.mk
Expand Down
Loading