Skip to content

Commit

Permalink
exercise 7 - packet transmission from kernel or user space
Browse files Browse the repository at this point in the history
  • Loading branch information
phlalx committed May 23, 2017
1 parent 072d141 commit a83c93b
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 2 deletions.
1 change: 1 addition & 0 deletions inc/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum {
E_FILE_EXISTS , // File already exists
E_NOT_EXEC , // File not a valid executable
E_NOT_SUPP , // Operation not supported
E_ETH_OVF , // Ethernet buffer is full

MAXERROR
};
Expand Down
1 change: 1 addition & 0 deletions inc/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ int sys_page_map(envid_t src_env, void *src_pg,
int sys_page_unmap(envid_t env, void *pg);
int sys_ipc_try_send(envid_t to_env, uint32_t value, void *pg, int perm);
int sys_ipc_recv(void *rcv_pg);
int sys_send_packet(void *buffer, size_t length);
unsigned int sys_time_msec(void);

// This must be inlined. Exercise for reader: why?
Expand Down
2 changes: 2 additions & 0 deletions inc/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ enum {
SYS_ipc_try_send,
SYS_ipc_recv,
SYS_time_msec,
SYS_send_packet,
SYS_receive_packet,
NSYSCALLS
};

Expand Down
1 change: 1 addition & 0 deletions kern/Makefrag
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ KERN_BINFILES += user/testfile \

# Binary files for LAB6
KERN_BINFILES += user/testtime \
user/testethsend\
user/httpd \
user/echosrv \
user/echotest \
Expand Down
45 changes: 44 additions & 1 deletion kern/e1000.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <kern/e1000.h>
#include <kern/pmap.h>
#include <inc/string.h>

volatile uint32_t *e1000;

Expand All @@ -8,7 +9,11 @@ volatile uint32_t *e1000;
uint8_t send_buffer[TDLEN][MTU];
// align this on 16-bytes boundary

struct tx_desc descs[TDLEN];
struct tx_desc descs[TDLEN] = { {0} };


static int cur = 0;


int e1000_attach_fn(struct pci_func *pcif) {
pci_func_enable(pcif);
Expand All @@ -28,6 +33,44 @@ int e1000_attach_fn(struct pci_func *pcif) {
e1000[E1000_TIPG] = 10 << E1000_IGPT_SHIFT | 10 << E1000_IGPR1_SHIFT
| 10 << E1000_IGPR2_SHIFT; // TODO revoir totalement ça ! 10.4.34


int i = 0;
for (i = 0; i < TDLEN; i++) {
// has to be set the first time we use a descriptor
// we use this bit to make sure a descriptor is available
// set by the hardware after the first use
descs[i].status = E1000_TXD_STAT_DD;
}

// TODO que renvoyer ?
return 0;
}

int e1000_send_packet(void *buffer, size_t length) {
assert(length <= MTU);

if (!(descs[cur].status & E1000_TXD_STAT_DD)) {
cprintf("can't reuse %d\n", cur);
return -1;
}

memset(&descs[cur], 0, sizeof(struct tx_desc));
memcpy(send_buffer[cur], buffer, length);

descs[cur].addr = (uint64_t) PADDR(send_buffer[cur]);
descs[cur].length = (uint32_t) length;

// set RS bit to know when descriptor has been used and can be recycled
// (DD bit is set when that happens)
uint8_t cmd = E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP;
descs[cur].cmd = cmd;

cur = (cur + 1) % TDLEN;
e1000[E1000_TDT] = cur;

return 0;
}




7 changes: 6 additions & 1 deletion kern/e1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@
#define E1000_IGPT_SHIFT 0
#define E1000_IGPR1_SHIFT 10
#define E1000_IGPR2_SHIFT 20


#define E1000_TXD_CMD_RS 0x08 /* Report Status */
#define E1000_TXD_CMD_EOP 0x01 /* Report Status */
#define E1000_TXD_STAT_DD 0x01 /* Descriptor Done */
#define MTU 1518

struct tx_desc
Expand All @@ -66,4 +69,6 @@ struct tx_desc

int e1000_attach_fn(struct pci_func *pcif);

int e1000_send_packet(void *buffer, size_t length);

#endif // JOS_KERN_E1000_H
32 changes: 32 additions & 0 deletions kern/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <kern/console.h>
#include <kern/sched.h>
#include <kern/time.h>
#include <kern/e1000.h>

// Print a string to the system console.
// The string is exactly 'len' characters long.
Expand Down Expand Up @@ -301,6 +302,9 @@ sys_page_map(envid_t srcenvid, void *srcva,
if ((err = page_insert(dstenv->env_pgdir, p, dstva, perm))) {
return err;
}


// TODO utiliser user_mem_check ?
return 0;
}

Expand Down Expand Up @@ -466,6 +470,31 @@ sys_time_msec(void)
return time_msec();
}


// return 0 on success.
// Return < 0 on error. Errors are:
// -E_INVAL if buffer isn't readable in user space
// -E_INVAL if len > MTU
static int
sys_send_packet(void *buffer, size_t length) {

if (length > MTU) {
return -E_INVAL;
}
int r = user_mem_check(curenv, buffer, length, 0);
if (r) {
return -E_INVAL;
}

r = e1000_send_packet(buffer, length);
if (r == -1) {
r = -E_ETH_OVF;
}

return r;
}


// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
Expand Down Expand Up @@ -524,6 +553,9 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
case SYS_time_msec:
res = sys_time_msec();
break;
case SYS_send_packet:
res = sys_send_packet((void *) a1, (int) a2);
break;
case NSYSCALLS:
default:
res = -E_INVAL;
Expand Down
5 changes: 5 additions & 0 deletions lib/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,8 @@ sys_time_msec(void)
{
return (unsigned int) syscall(SYS_time_msec, 0, 0, 0, 0, 0, 0);
}

int
sys_send_packet(void *buffer, size_t length) {
return syscall(SYS_send_packet, 0, (uint32_t) buffer, (uint32_t) length, 0, 0, 0);
}
20 changes: 20 additions & 0 deletions user/testethsend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <inc/lib.h>

#define N 50
#define MAX_LEN 100

char buffer[N][MAX_LEN];

void
umain(int argc, char **argv)
{
int i = 0;

for (i = 0; i < N; i++) {
snprintf(buffer[i], MAX_LEN, "hello %d\n", i);
}

for (i = 0; i < N; i++) {
sys_send_packet(buffer[i], strlen(buffer[i]));
}
}

0 comments on commit a83c93b

Please sign in to comment.