1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add IP interface between HermitCore and Linux

This commit is contained in:
Stefan Lankes 2015-09-30 12:27:02 +02:00
parent 61d86522d5
commit 67b46926b1
13 changed files with 1852 additions and 9 deletions

View file

@ -3,7 +3,8 @@ TOPDIR := $(shell pwd)
ARCH = x86
NAME = hermit
LWIPDIRS = lwip/src/arch lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif
KERNDIRS = kernel mm libkern fs arch/$(ARCH)/kernel arch/$(ARCH)/mm $(LWIPDIRS)
DRIVERDIRS = drivers/net
KERNDIRS = kernel mm libkern fs arch/$(ARCH)/kernel arch/$(ARCH)/mm $(LWIPDIRS) $(DRIVERDIRS)
SUBDIRS = $(KERNDIRS)
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags)
TODAY := $(shell date +'%Y%m%d')
@ -46,7 +47,7 @@ QEMUDEBUGFLAGS = -monitor none -daemonize \
QEMUSERIALFLAGS = -device pci-serial,chardev=tS0 \
-chardev socket,host=localhost,port=4555,server,id=tS0
INCLUDE = -I$(TOPDIR)/include -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/lwip/src/include -I$(TOPDIR)/lwip/src/include/ipv4
INCLUDE = -I$(TOPDIR)/include -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/lwip/src/include -I$(TOPDIR)/lwip/src/include/ipv4 -I$(TOPDIR)/drivers
# Compiler options for final code
CFLAGS = -DVERSION=\"$(GIT_VERSION)\" -D_HERMIT -g -m64 -Wall -O2 -mno-red-zone -fno-var-tracking-assignments -fstrength-reduce -fomit-frame-pointer -finline-functions -ffreestanding -nostdinc -fno-stack-protector $(INCLUDE)
# Compiler options for debugging

View file

@ -203,6 +203,7 @@ int apic_calibration(void);
int apic_is_enabled(void);
int apic_enable_timer(void);
int apic_disable_timer(void);
int apic_send_ipi(uint64_t dest, uint8_t irq);
int ioapic_inton(uint8_t irq, uint8_t apicid);
int ioapic_intoff(uint8_t irq, uint8_t apicid);
int map_apic(void);

View file

@ -618,9 +618,9 @@ static inline void set_ipi_dest(uint32_t cpu_id) {
int ipi_tlb_flush(void)
{
uint32_t id = CORE_ID;
uint32_t flags;
uint32_t j;
uint64_t i;
uint8_t flags;
if (atomic_int32_read(&cpu_online) == 1)
return 0;
@ -677,6 +677,38 @@ static void apic_tlb_handler(struct state *s)
}
#endif
int apic_send_ipi(uint64_t dest, uint8_t irq)
{
uint32_t j;
uint8_t flags;
if (BUILTIN_EXPECT(has_x2apic(), 1)) {
flags = irq_nested_disable();
//kprintf("send IPI %d to %lld\n", (int)irq, dest);
wrmsr(0x830, (dest << 32)|APIC_INT_ASSERT|APIC_DM_FIXED|irq);
irq_nested_enable(flags);
} else {
if (lapic_read(APIC_ICR1) & APIC_ICR_BUSY) {
kputs("ERROR: previous send not complete");
return -EIO;
}
flags = irq_nested_disable();
//kprintf("send IPI %d to %lld\n", (int)irq, dest);
set_ipi_dest((uint32_t)dest);
lapic_write(APIC_ICR1, APIC_INT_ASSERT|APIC_DM_FIXED|irq);
j = 0;
while((lapic_read(APIC_ICR1) & APIC_ICR_BUSY) && (j < 1000))
j++; // wait for it to finish, give up eventualy tho
irq_nested_enable(flags);
}
return 0;
}
static void apic_err_handler(struct state *s)
{
kprintf("Got APIC error 0x%x\n", lapic_read(APIC_ESR));

View file

@ -57,6 +57,14 @@ align 4
global timer_ticks
global current_boot_id
global isle
global possible_isles
global phy_isle_locks
global heap_phy_start_address
global header_phy_start_address
global heap_start_address
global header_start_address
global heap_size
global header_size
base dq 0
limit dq 0
cpu_freq dd 0
@ -67,6 +75,14 @@ align 4
current_boot_id dd 0
isle dd -1
image_size dq 0
phy_isle_locks dq 0
heap_phy_start_address dq 0
header_phy_start_address dq 0
heap_size dd 0
header_size dd 0
possible_isles dd 1
heap_start_address dq 0
header_start_address dq 0
; Bootstrap page tables are used during the initialization.
align 4096
@ -346,6 +362,13 @@ apic_svr:
push byte 127
jmp common_stub
global mmnif_irq
align 16
mmnif_irq:
push byte 0 ; pseudo error code
push byte 122
jmp common_stub
extern irq_handler
extern get_current_stack
extern finish_task_switch

View file

@ -78,6 +78,7 @@ extern void apic_lint0(void);
extern void apic_lint1(void);
extern void apic_error(void);
extern void apic_svr(void);
extern void mmnif_irq(void);
#define MAX_HANDLERS 256
@ -217,6 +218,9 @@ static int irq_install(void)
idt_set_gate(113, (size_t)irq81, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(122, (size_t)mmnif_irq, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// add APIC interrupt handler
idt_set_gate(123, (size_t)apic_timer, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);

View file

@ -0,0 +1,4 @@
C_source := mmnif.c util.c
MODULE := drivers_net
include $(TOPDIR)/Makefile.inc

1553
hermit/drivers/net/mmnif.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
/*
* Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems,
* RWTH Aachen University
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2 (https://www.gnu.org/licenses/gpl-2.0.txt)
* or the BSD license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MMNIF_H__
#define __MMNIF_H__
#include <hermit/stddef.h>
#include <lwip/err.h>
#include <lwip/netif.h> /* lwip netif */
#include <lwip/sockets.h>
#define AF_MMNIF_NET 0x42
#define MMNIF_AUTOACTIVATE_FAST_SOCKETS LWIP_SOCKET
#if MMNIF_AUTOACTIVATE_FAST_SOCKETS
int mmnif_socket(int domain, int type, int protocol);
int mmnif_send(int s, void *data, size_t size, int flags);
int mmnif_recv(int s, void *data, uint32_t len, int flags);
int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen);
int mmnif_connect(int s, const struct sockaddr *name, socklen_t namelen);
int mmnif_listen(int s, int backlog);
int mmnif_bind(int s, const struct sockaddr *name, socklen_t namelen);
int mmnif_closesocket(int s);
int mmnif_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
int mmnif_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
#undef accept
#define accept(a,b,c) mmnif_accept(a,b,c)
#undef closesocket
#define closesocket(s) mmnif_closesocket(s)
#undef connect
#define connect(a,b,c) mmnif_connect(a,b,c)
#undef recv
#define recv(a,b,c,d) mmnif_recv(a,b,c,d)
#undef send
#define send(a,b,c,d) mmnif_send(a,b,c,d)
#undef socket
#define socket(a,b,c) mmnif_socket(a,b,c)
#undef bind
#define bind(a,b,c) mmnif_bind(a,b,c)
#undef listen
#define listen(a,b) mmnif_listen(a,b)
#undef setsockopt
#define setsockopt(a,b,c,d,e) mmnif_setsockopt(a,b,c,d,e)
#undef select
#endif
err_t mmnif_init(struct netif*);
err_t mmnif_shutdown(void);
int mmnif_worker(void *e);
void mmnif_print_driver_status(void);
#endif

66
hermit/drivers/net/util.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems,
* RWTH Aachen University
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2 (https://www.gnu.org/licenses/gpl-2.0.txt)
* or the BSD license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <hermit/stdio.h>
#include "util.h"
inline int isprint(unsigned char e)
{
if ((e < 0x30) || (e > 0x80))
return 0;
return 1;
}
// hex_dumb display network packets in a good way
void hex_dump(unsigned n, const unsigned char *buf)
{
int on_this_line = 0;
while (n-- > 0)
{
kprintf("%02X ", *buf++);
on_this_line += 1;
if (on_this_line == 16 || n == 0)
{
int i;
kputs(" ");
for (i = on_this_line; i < 16; i++)
kputs(" ");
for (i = on_this_line; i > 0; i--)
kputchar(isprint(buf[-i]) ? buf[-i] : '.');
kputs("\n");
on_this_line = 0;
}
}
}

39
hermit/drivers/net/util.h Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems,
* RWTH Aachen University
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2 (https://www.gnu.org/licenses/gpl-2.0.txt)
* or the BSD license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __UTIL__
#define __UTIL__
// hex_dumb display network packets in a good way
void hex_dump(unsigned n, const unsigned char *buf);
#endif

View file

@ -34,6 +34,7 @@ extern "C" {
#define MAX_CORES 40
#define MAX_TASKS 16
#define MAX_ISLE 8
#define MAX_FNAME 128
#define TIMER_FREQ 100 /* in HZ */
#define CLOCK_TICK_RATE 1193182 /* 8254 chip's internal oscillator frequency */

View file

@ -49,6 +49,9 @@
#include <lwip/netifapi.h>
#include <lwip/timers.h>
#include <netif/etharp.h>
#include <net/mmnif.h>
static struct netif mmnif_netif;
/*
* Note that linker symbols are not variables, they have no memory allocated for
@ -71,6 +74,7 @@ extern atomic_int64_t total_available_pages;
extern atomic_int32_t cpu_online;
extern atomic_int32_t possible_cpus;
extern int32_t isle;
extern int32_t possible_isles;
static int foo(void* arg)
{
@ -127,6 +131,10 @@ static void tcpip_init_done(void* arg)
static int init_netifs(void)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
err_t err;
sys_sem_t sem;
if(sys_sem_new(&sem, 0) != ERR_OK)
@ -137,6 +145,31 @@ static int init_netifs(void)
kprintf("TCP/IP initialized.\n");
sys_sem_free(&sem);
/* Set network address variables */
IP4_ADDR(&gw, 192,168,28,1);
IP4_ADDR(&ipaddr, 192,168,28,isle+2);
IP4_ADDR(&netmask, 255,255,255,0);
/* register our Memory Mapped Virtual IP interface in the lwip stack
* and tell him how to use the interface:
* - mmnif_dev : the device data storage
* - ipaddr : the ip address wich should be used
* - gw : the gateway wicht should be used
* - mmnif_init : the initialization which has to be done in order to use our interface
* - ip_input : tells him that he should use ip_input
*
* Note: Our drivers guarantee that the input function will be called in the context of the tcpip thread.
* => Therefore, we are able to use ip_input instead of tcpip_input */
if ((err = netifapi_netif_add(&mmnif_netif, &ipaddr, &netmask, &gw, NULL, mmnif_init, ip_input)) != ERR_OK)
{
kprintf("Unable to add the intra network interface: err = %d\n", err);
return -ENODEV;
}
/* tell lwip all initialization is done and we want to set it up */
netifapi_netif_set_default(&mmnif_netif);
netifapi_netif_set_up(&mmnif_netif);
return 0;
}
@ -169,10 +202,10 @@ int smp_main(void)
// init task => creates all other tasks an initialize the LwIP
static int initd(void* arg)
{
char* argv1[] = {"/bin/hello", NULL};
char* argv2[] = {"/bin/jacobi", NULL};
char* argv3[] = {"/bin/stream", NULL};
char* argv4[] = {"/bin/thr_hello", NULL};
//char* argv1[] = {"/bin/hello", NULL};
//char* argv2[] = {"/bin/jacobi", NULL};
//char* argv3[] = {"/bin/stream", NULL};
//char* argv4[] = {"/bin/thr_hello", NULL};
init_netifs();
@ -181,7 +214,7 @@ static int initd(void* arg)
//create_user_task(NULL, "/bin/hello", argv1, NORMAL_PRIO);
//create_user_task(NULL, "/bin/jacobi", argv2, NORMAL_PRIO);
//create_user_task(NULL, "/bin/jacobi", argv2, NORMAL_PRIO);
create_user_task(NULL, "/bin/stream", argv3, NORMAL_PRIO);
//create_user_task(NULL, "/bin/stream", argv3, NORMAL_PRIO);
//create_user_task(NULL, "/bin/thr_hello", argv4, NORMAL_PRIO);
return 0;
@ -195,6 +228,7 @@ int main(void)
atomic_int32_inc(&cpu_online);
kprintf("This is Hermit %s, build date %u\n", VERSION, &__BUILD_DATE);
kprintf("Isle %d of %d possible isles\n", isle, possible_isles);
kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end);
kprintf("Per core data starts at %p and ends at %p\n", &percore_start, &percore_end);
kprintf("Per core size 0x%zd\n", (size_t) &percore_end0 - (size_t) &percore_start);

@ -1 +1 @@
Subproject commit 57ff67f87b9e02ee8ec1089a1e971b96f08555a4
Subproject commit 6dbcf238e2e6abe4ae90a8c64521fbf8d75c3ce3