Merge branch 'master' into ohligs
Conflicts: kernel/init.c kernel/tests.c
This commit is contained in:
commit
e572d1c502
32 changed files with 1029 additions and 170 deletions
|
@ -75,6 +75,21 @@ inline static void irq_nested_enable(uint32_t flags) {
|
|||
irq_enable();
|
||||
}
|
||||
|
||||
/** @brief Determines, if the interrupt flags (IF) is ser
|
||||
*
|
||||
* @return
|
||||
* - 1 interrupt flag is set
|
||||
* - 0 interrupt flag is cleared
|
||||
*/
|
||||
inline static uint32_t is_irq_enabled(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
asm volatile("pushf; popl %0": "=r"(flags) : : "memory");
|
||||
if (flags & (1 << 9))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -272,22 +272,42 @@ static inline uint32_t read_eflags(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
/** @brief search the first bit, which is set
|
||||
/** @brief search the first most significant bit
|
||||
*
|
||||
* @param i source operand
|
||||
* @return first bit, which is set in the source operand
|
||||
* @return
|
||||
* - first bit, which is set in the source operand
|
||||
* - invalid value, if not bit ist set
|
||||
*/
|
||||
static inline uint32_t last_set(uint32_t i)
|
||||
static inline size_t msb(size_t i)
|
||||
{
|
||||
uint32_t ret;
|
||||
size_t ret;
|
||||
|
||||
if (!i)
|
||||
return 0;
|
||||
return (sizeof(size_t)*8);
|
||||
asm volatile ("bsr %1, %0" : "=r"(ret) : "r"(i) : "cc");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @brief search the least significant bit
|
||||
*
|
||||
* @param i source operand
|
||||
* @return
|
||||
* - first bit, which is set in the source operand
|
||||
* - invalid value, if not bit ist set
|
||||
*/
|
||||
static inline size_t lsb(size_t i)
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
if (!i)
|
||||
return (sizeof(size_t)*8);
|
||||
asm volatile ("bsf %1, %0" : "=r"(ret) : "r"(i) : "cc");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @brief Read extended instruction pointer
|
||||
* @return The EIP's value
|
||||
*/
|
||||
|
|
|
@ -237,8 +237,7 @@ void irq_handler(struct state *s)
|
|||
// evaluate only irq status register if int_no = 124
|
||||
if( s->int_no == 124 ) {
|
||||
check_workqueues_rem_irq();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
check_workqueues();
|
||||
}
|
||||
|
||||
|
@ -283,4 +282,6 @@ leave_handler:
|
|||
// timer interrupt?
|
||||
if ((s->int_no == 32) || (s->int_no == 123))
|
||||
scheduler(); // switch to a new task
|
||||
else if ((s->int_no >= 32) && (get_highest_priority() > per_core(current_task)->prio))
|
||||
scheduler();
|
||||
}
|
||||
|
|
|
@ -367,6 +367,9 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag
|
|||
if (flags & MAP_NO_ACCESS)
|
||||
pgt->entries[index] &= ~PG_PRESENT;
|
||||
|
||||
if (flags & MAP_WT)
|
||||
pgt->entries[index] |= PG_PWT;
|
||||
|
||||
if (flags & MAP_USER_SPACE)
|
||||
atomic_int32_inc(&task->user_usage);
|
||||
|
||||
|
@ -801,8 +804,9 @@ int arch_paging_init(void)
|
|||
npages = bootinfo->size >> PAGE_SHIFT;
|
||||
if (bootinfo->size & (PAGE_SIZE-1))
|
||||
npages++;
|
||||
bootinfo->addr = map_region(0, bootinfo->addr, npages, MAP_KERNEL_SPACE);
|
||||
kprintf("Map initrd at 0x%x (size %u bytes)\n", bootinfo->addr, bootinfo->size);
|
||||
viraddr = map_region(0, bootinfo->addr, npages, MAP_KERNEL_SPACE);
|
||||
kprintf("Map initrd from 0x%x to 0x%x (size %u bytes)\n", bootinfo->addr, viraddr, bootinfo->size);
|
||||
bootinfo->addr = viraddr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -132,7 +132,7 @@ int svm_access_request(size_t addr)
|
|||
icc_mail_check(0);
|
||||
|
||||
while (page_owner[pageid] != my_ue) {
|
||||
check_workqueues_rem_irq();
|
||||
check_workqueues();
|
||||
}
|
||||
|
||||
return change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
|
||||
|
|
|
@ -257,7 +257,7 @@ int icc_halt(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define ROUNDS 100000
|
||||
#define ROUNDS 1000
|
||||
#define CORE_A 0 // sender
|
||||
#define CORE_B 1 // receiver
|
||||
|
||||
|
@ -425,7 +425,7 @@ int icc_mail_ping_irq(void)
|
|||
|
||||
kprintf( "timer = %d\n", timer );
|
||||
kprintf( "mail_pingpong needs in average %d nsec (%d ticks)!\n",
|
||||
timer*1000/(2*ROUNDS*533), timer/(2*ROUNDS) );
|
||||
timer*1000/(2*ROUNDS*get_cpu_frequency()), timer/(2*ROUNDS) );
|
||||
|
||||
|
||||
irq_nested_enable(flags);
|
||||
|
|
|
@ -101,9 +101,6 @@
|
|||
#define CLINE_ALIGN(_x) (((_x) + CLINE_SIZE - 1) & CLINE_MASK)
|
||||
#define CLINE_PACKETS(_x) (CLINE_ALIGN(_x) >> CLINE_SHIFT)
|
||||
|
||||
/* Flush */
|
||||
#define CL1FLUSH __asm__ volatile (".byte 0x0F; .byte 0x0A;\n")
|
||||
|
||||
/* Read 16bit from buffer */
|
||||
#define U16(_addr) (256 * (*((uint8_t*) (_addr + 1))) + (*((uint8_t*)(_addr))))
|
||||
|
||||
|
@ -111,8 +108,80 @@
|
|||
#define MAC_HI(_x) ((((_x) >> 32)) & 0xFFFF)
|
||||
#define MAC_LO(_x) (((_x) ) & 0xFFFFFFFF)
|
||||
|
||||
#define MIN(a, b) (a) < (b) ? (a) : (b)
|
||||
|
||||
static struct netif* mynetif;
|
||||
|
||||
inline static void* memcpy_from_nc(void *dest, const void *src, size_t count)
|
||||
{
|
||||
#if 0
|
||||
size_t i;
|
||||
|
||||
for(i=0; i<count; i++)
|
||||
((uint8_t*) dest)[i] = ((uint8_t*) src)[i];
|
||||
|
||||
return dest;
|
||||
#else
|
||||
int32_t h, i, j, k, l, m;
|
||||
|
||||
asm volatile ("cld;\n\t"
|
||||
"1: cmpl $0, %%eax ; je 3f\n\t"
|
||||
"movl (%%edi), %%edx\n\t"
|
||||
"cmpl $1, %%eax ; je 2f\n\t"
|
||||
"movl 32(%%edi), %%edx\n\t"
|
||||
"2: movl 0(%%esi), %%ecx\n\t"
|
||||
"movl 4(%%esi), %%edx\n\t"
|
||||
"movl %%ecx, 0(%%edi)\n\t"
|
||||
"movl %%edx, 4(%%edi)\n\t"
|
||||
"movl 8(%%esi), %%ecx\n\t"
|
||||
"movl 12(%%esi), %%edx\n\t"
|
||||
"movl %%ecx, 8(%%edi)\n\t"
|
||||
"movl %%edx, 12(%%edi)\n\t"
|
||||
"movl 16(%%esi), %%ecx\n\t"
|
||||
"movl 20(%%esi), %%edx\n\t"
|
||||
"movl %%ecx, 16(%%edi)\n\t"
|
||||
"movl %%edx, 20(%%edi)\n\t"
|
||||
"movl 24(%%esi), %%ecx\n\t"
|
||||
"movl 28(%%esi), %%edx\n\t"
|
||||
"movl %%ecx, 24(%%edi)\n\t"
|
||||
"movl %%edx, 28(%%edi)\n\t"
|
||||
"addl $32, %%esi\n\t"
|
||||
"addl $32, %%edi\n\t"
|
||||
"dec %%eax ; jmp 1b\n\t"
|
||||
"3: movl %%ebx, %%ecx\n\t"
|
||||
"movl (%%edi), %%edx\n\t"
|
||||
"andl $31, %%ecx\n\t"
|
||||
"rep ; movsb\n\t" : "=&a"(h), "=&D"(i), "=&S"(j), "=&b"(k), "=&c"(l), "=&d"(m)
|
||||
: "0"(count / 32), "1"(dest), "2"(src), "3"(count) : "memory","cc");
|
||||
|
||||
return dest;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static void* memcpy_to_nc(void* dest, const void *src, size_t count)
|
||||
{
|
||||
#if 0
|
||||
size_t i;
|
||||
|
||||
for(i=0; i<count; i++)
|
||||
((uint8_t*) dest)[i] = ((uint8_t*) src)[i];
|
||||
|
||||
return dest;
|
||||
#else
|
||||
int32_t i, j, k;
|
||||
|
||||
asm volatile (
|
||||
"cld; rep movsl\n\t"
|
||||
"movl %4, %%ecx\n\t"
|
||||
"andl $3, %%ecx\n\t"
|
||||
"rep movsb\n\t"
|
||||
: "=&c"(i), "=&D"(j), "=&S"(k)
|
||||
: "0"(count/4), "g"(count), "1"(dest), "2"(src) : "memory","cc");
|
||||
|
||||
return dest;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int read_emac(int num_emac, int offset, int core)
|
||||
{
|
||||
int ret;
|
||||
|
@ -190,7 +259,7 @@ again:
|
|||
* This list MUST consist of a single packet ONLY
|
||||
*/
|
||||
for (q=p, i=0; q!=0; q=q->next) {
|
||||
memcpy(((uint8_t*)addr) + 2 + i, q->payload, q->len);
|
||||
memcpy_to_nc(((uint8_t*)addr) + 2 + i, q->payload, q->len);
|
||||
i += q->len;
|
||||
}
|
||||
|
||||
|
@ -207,12 +276,12 @@ again:
|
|||
if (bytes_left < bytes_to_copy)
|
||||
bytes_to_copy = bytes_left;
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy last %d bytes\n", bytes_to_copy));
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy last %d bytes\n", bytes_to_copy));
|
||||
|
||||
q = p; i = 0;
|
||||
while ((q != 0) && (i < bytes_to_copy)) {
|
||||
sz = q->len > bytes_to_copy-i ? bytes_to_copy-i : q->len;
|
||||
memcpy(((uint8_t*) addr) + 2 + i, q->payload, sz);
|
||||
memcpy_to_nc(((uint8_t*) addr) + 2 + i, q->payload, sz);
|
||||
bytes_left -= sz;
|
||||
i += sz;
|
||||
if (i < bytes_to_copy)
|
||||
|
@ -222,16 +291,16 @@ again:
|
|||
if (bytes_left != 0) {
|
||||
rckemacif->tx_write_offset = 1;
|
||||
addr = rckemacif->tx_buffer + 32;
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy remaining %d bytes\n", bytes_left));
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy remaining %d bytes\n", bytes_left));
|
||||
|
||||
i = 0;
|
||||
if (sz < q->len) {
|
||||
memcpy((uint8_t*) addr, q->payload + sz, q->len - sz);
|
||||
memcpy_to_nc((uint8_t*) addr, q->payload + sz, q->len - sz);
|
||||
bytes_left -= (q->len - sz);
|
||||
i = q->len - sz;
|
||||
}
|
||||
for(q=q->next; (q != 0); q = q->next) {
|
||||
memcpy(((uint8_t*) addr) + i, q->payload, q->len);
|
||||
memcpy_to_nc(((uint8_t*) addr) + i, q->payload, q->len);
|
||||
i += q->len;
|
||||
}
|
||||
|
||||
|
@ -239,13 +308,16 @@ again:
|
|||
if (rest != 0)
|
||||
rest = 32 - rest;
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Rest is %d\n", rest));
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("Rest is %d\n", rest));
|
||||
rckemacif->tx_write_offset += CLINE_PACKETS(bytes_left + rest) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
*((volatile int*) rckemacif->tx_buffer) = 2;
|
||||
|
||||
// flush write combining buffers
|
||||
*(int *)RCCE_fool_write_combine_buffer = 1;
|
||||
|
||||
/* set new write offset */
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset));
|
||||
write_emac(rckemacif->num_emac, EMAC_TX_CONTROL+EMAC_TX_BUFFER_WRITE_OFFSET, rckemacif->core, rckemacif->tx_write_offset);
|
||||
|
@ -292,7 +364,7 @@ static void rckemacif_rx_handler(struct netif* netif, unsigned int write_offset)
|
|||
{
|
||||
rckemacif_t* rckemacif = netif->state;
|
||||
unsigned short read_offset = rckemacif->rx_read_offset;
|
||||
unsigned int counter;
|
||||
//unsigned int counter;
|
||||
volatile void *addr = NULL;
|
||||
uint16_t i, length = 0;
|
||||
uint32_t packets = 0;
|
||||
|
@ -353,7 +425,7 @@ again:
|
|||
|
||||
if (read_offset < write_offset) {
|
||||
for (q=p, i/*counter=0*/; q!=NULL; q=q->next) {
|
||||
memcpy((uint8_t*) q->payload, (uint8_t*)addr + 2, q->len);
|
||||
memcpy_from_nc((uint8_t*) q->payload, (uint8_t*)addr + 2, q->len);
|
||||
//for(i=0; i<q->len; i++, counter++) {
|
||||
// ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter];
|
||||
//}
|
||||
|
@ -364,33 +436,52 @@ again:
|
|||
int rest;
|
||||
int bytesLeft = length;
|
||||
int bytesToCopy = length;
|
||||
int counter = 0;
|
||||
|
||||
/* rest to the end of buffer - 2 bytes length information */
|
||||
rest = (rckemacif->rx_buffer_max - read_offset + 1) * 32 - 2;
|
||||
if (length > rest)
|
||||
bytesToCopy = rest;
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("bytes to copy: %d, bytesLeft: %d\n", bytesToCopy, bytesLeft));
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("bytes to copy: %d, bytesLeft: %d\n", bytesToCopy, bytesLeft));
|
||||
|
||||
for (q=p, counter=0; q!=NULL; q=q->next) {
|
||||
for(i=0; i<q->len; i++, counter++) {
|
||||
q = p;
|
||||
i = /*counter =*/ 0;
|
||||
while ((q != NULL) && (counter < bytesToCopy)) {
|
||||
i = MIN(q->len, bytesToCopy - counter);
|
||||
memcpy_from_nc(q->payload, (uint8_t*) addr + 2 + counter, i);
|
||||
counter += i;
|
||||
if (counter >= bytesToCopy)
|
||||
goto out;
|
||||
else
|
||||
q = q->next;
|
||||
/*for(i=0; i<q->len; i++, counter++) {
|
||||
if (counter < bytesToCopy)
|
||||
((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter];
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
out:
|
||||
bytesLeft -= bytesToCopy;
|
||||
|
||||
if (bytesLeft != 0) {
|
||||
addr = rckemacif->rx_buffer + 0x20;
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("copying from %p, left: %d (%x)\n", addr, bytesLeft, ((uint8_t*)addr)[0]));
|
||||
for(counter=0; (i<q->len) && (counter < bytesLeft); i++, counter++)
|
||||
((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter];
|
||||
counter = 0;
|
||||
//LWIP_DEBUGF(NETIF_DEBUG, ("copying from %p, left: %d (%x)\n", addr, bytesLeft, ((uint8_t*)addr)[0]));
|
||||
|
||||
if (i < q->len) {
|
||||
counter = MIN(q->len - i, bytesLeft);
|
||||
memcpy_from_nc((uint8_t*)q->payload + i, (uint8_t*) addr, counter);
|
||||
}
|
||||
//for(counter=0; (i<q->len) && (counter < bytesLeft); i++, counter++)
|
||||
// ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter];
|
||||
for(q=q->next; (q!=NULL) && (counter < bytesLeft); q=q->next) {
|
||||
for(i=0; (i<q->len) && (counter < bytesLeft); i++, counter++) {
|
||||
((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter];
|
||||
}
|
||||
i = MIN(q->len, bytesLeft - counter);
|
||||
memcpy_from_nc((uint8_t*)q->payload, (uint8_t*)addr + counter, i);
|
||||
counter += i;
|
||||
//for(i=0; (i<q->len) && (counter < bytesLeft); i++, counter++) {
|
||||
// ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter];
|
||||
//}
|
||||
}
|
||||
read_offset = CLINE_PACKETS(bytesLeft);
|
||||
} else {
|
||||
|
@ -439,7 +530,6 @@ static void rckemacif_handler(struct state* s)
|
|||
|
||||
nexttry:
|
||||
/* check for updated write offset */
|
||||
CL1FLUSH;
|
||||
write_offset = *((volatile unsigned int*) (rckemacif->rx_buffer)) & 0xFFFF;
|
||||
//write_offset = read_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, rckemacif->core);
|
||||
if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset)) {
|
||||
|
@ -500,7 +590,7 @@ err_t rckemacif_init(struct netif* netif)
|
|||
rckemacif->rx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1;
|
||||
|
||||
/* allocate the send buffers */
|
||||
rckemacif->tx_buffer = mem_allocation(BUFFER_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE);
|
||||
rckemacif->tx_buffer = mem_allocation(BUFFER_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE|MAP_WT|MAP_MPE);
|
||||
if (!(rckemacif->tx_buffer)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: out of memory\n"));
|
||||
kfree(rckemacif->rx_buffer, BUFFER_SIZE);
|
||||
|
@ -762,7 +852,8 @@ err_t rckemacif_init(struct netif* netif)
|
|||
|
||||
rckemacif->ethaddr = (struct eth_addr *)netif->hwaddr;
|
||||
|
||||
tcpip_callback(netif_set_link_up, netif);
|
||||
// flush write combining buffers
|
||||
*(int *)RCCE_fool_write_combine_buffer = 1;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
|
|
@ -441,14 +441,12 @@ err_t rtl8139if_init(struct netif* netif)
|
|||
/* maximum transfer unit */
|
||||
netif->mtu = 1500;
|
||||
/* broadcast capability */
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
|
||||
/* hardware address length */
|
||||
netif->hwaddr_len = 6;
|
||||
|
||||
rtl8139if->ethaddr = (struct eth_addr *)netif->hwaddr;
|
||||
|
||||
tcpip_callback(netif_set_link_up, netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,11 +36,8 @@ extern "C" {
|
|||
* initialize the VGA output. If configured.*/
|
||||
int lowlevel_init(void);
|
||||
|
||||
/** @brief Initialize LWIP stack and start a networking task. */
|
||||
int network_init(void);
|
||||
|
||||
/** @brief Shutdown the networking subsystem. */
|
||||
int network_shutdown(void);
|
||||
/** @brief Shutdown the system */
|
||||
int shutdown(void);
|
||||
|
||||
/** @brief Entry point of the init task */
|
||||
int initd(void* arg);
|
||||
|
|
|
@ -41,7 +41,7 @@ extern "C" {
|
|||
#define MAP_USER_SPACE (1 << 1)
|
||||
#define MAP_PAGE_TABLE (1 << 2)
|
||||
#define MAP_NO_CACHE (1 << 3)
|
||||
//#define MAP_STACK (1 << 4)
|
||||
#define MAP_WT (1 << 5)
|
||||
//#define MAP_HEAP (1 << 5)
|
||||
#define MAP_CODE (1 << 6)
|
||||
#define MAP_READONLY (1 << 7)
|
||||
|
|
|
@ -176,12 +176,17 @@ size_t get_idle_task(uint32_t id);
|
|||
*/
|
||||
int sys_execve(const char* fname, char** argv, char** env);
|
||||
|
||||
/** @brief determines the highest priority of all ready tasks on core core_id
|
||||
*
|
||||
* @param core_id core id
|
||||
* @return highest priority
|
||||
/** @brief if a task exists with higher priority, MetalSVM switch to it.
|
||||
*/
|
||||
uint32_t get_highest_priority(uint32_t core_id);
|
||||
void check_scheduling(void);
|
||||
|
||||
/** @brief determine the highest priority of all tasks, which are ready
|
||||
*
|
||||
* @return
|
||||
* - return highest priority
|
||||
* - if no task is ready, the function returns an invalid value (> MAX_PRIO)
|
||||
*/
|
||||
uint32_t get_highest_priority(void);
|
||||
|
||||
/** @brief Call to rescheduling
|
||||
*
|
||||
|
@ -194,6 +199,7 @@ static inline void check_workqueues(void)
|
|||
#ifdef CONFIG_ROCKCREEK
|
||||
icc_mail_check(0);
|
||||
#endif
|
||||
check_scheduling();
|
||||
}
|
||||
|
||||
static inline void check_workqueues_rem_irq(void)
|
||||
|
|
144
kernel/init.c
144
kernel/init.c
|
@ -72,30 +72,14 @@ int lowlevel_init(void)
|
|||
|
||||
#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK))
|
||||
static struct netif* default_netif = NULL;
|
||||
static volatile uint32_t lwip_initialized = 0;
|
||||
|
||||
static void tcp_init_ok(void* e)
|
||||
static int init_netifs(void)
|
||||
{
|
||||
kputs("TCP/IP init COMPLETE!!\n");
|
||||
lwip_initialized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int network_init(void)
|
||||
{
|
||||
#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK))
|
||||
struct ip_addr ipaddr;
|
||||
struct ip_addr netmask;
|
||||
struct ip_addr gw;
|
||||
|
||||
kputs("Initialize network...\n");
|
||||
|
||||
// Initialize lwIP modules
|
||||
tcpip_init(tcp_init_ok, NULL);
|
||||
|
||||
while(!lwip_initialized) {
|
||||
reschedule();
|
||||
}
|
||||
kputs("Initialize NICs...\n");
|
||||
|
||||
// Set up the lwIP network interface
|
||||
// Allocate and configure netif
|
||||
|
@ -109,12 +93,20 @@ int network_init(void)
|
|||
memset(default_netif, 0x00, sizeof(struct netif));
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
/* Set network address variables */
|
||||
IP4_ADDR(&gw, 192,168,4,254);
|
||||
IP4_ADDR(&ipaddr, 192,168,4,RCCE_ue()+1);
|
||||
IP4_ADDR(&gw, 192,168,28,254);
|
||||
IP4_ADDR(&ipaddr, 192,168,28,RCCE_ue()+1);
|
||||
IP4_ADDR(&netmask, 255,255,255,0);
|
||||
|
||||
/* Bring up the network interface */
|
||||
if (!netif_add(default_netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, tcpip_input)) {
|
||||
kputs("Unable to add network interface\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
netif_set_default(default_netif);
|
||||
netif_set_up(default_netif);
|
||||
|
||||
//mmnif_open();
|
||||
#else
|
||||
/* Clear network address because we use DHCP to get an ip address */
|
||||
IP4_ADDR(&gw, 0,0,0,0);
|
||||
|
@ -123,63 +115,63 @@ int network_init(void)
|
|||
|
||||
/* Bring up the network interface */
|
||||
if (!netif_add(default_netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, tcpip_input)) {
|
||||
#endif
|
||||
kputs("Unable to add network interface\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
netif_set_default(default_netif);
|
||||
netif_set_up(default_netif);
|
||||
|
||||
/* test if interface is really up */
|
||||
if (!netif_is_up(default_netif)) {
|
||||
kputs("network interface is not up\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ROCKCREEK
|
||||
kprintf("Starting DHCPCD...\n");
|
||||
dhcp_start(default_netif);
|
||||
|
||||
int mscnt = 0;
|
||||
/* wait for ip address */
|
||||
while(!default_netif->ip_addr.addr) {
|
||||
sys_msleep(DHCP_FINE_TIMER_MSECS);
|
||||
dhcp_fine_tmr();
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
|
||||
dhcp_coarse_tmr();
|
||||
mscnt = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//mmnif_open();
|
||||
#endif
|
||||
|
||||
// start echo and ping server
|
||||
echo_init();
|
||||
//ping_init();
|
||||
netio_init();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int network_shutdown(void)
|
||||
{
|
||||
#ifdef CONFIG_LWIP
|
||||
static void tcpip_init_done(void* arg)
|
||||
{
|
||||
sys_sem_t* sem = (sys_sem_t*)arg;
|
||||
|
||||
#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK))
|
||||
init_netifs();
|
||||
#endif
|
||||
sys_sem_signal(sem);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LWIP
|
||||
static int network_shutdown(void)
|
||||
{
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
if (default_netif) {
|
||||
netif_set_link_down(default_netif);
|
||||
mem_free(default_netif);
|
||||
default_netif = NULL;
|
||||
}
|
||||
//mmnif_close();
|
||||
#elif defined(CONFIG_PCI)
|
||||
dhcp_release(default_netif);
|
||||
dhcp_stop(default_netif);
|
||||
if (default_netif) {
|
||||
dhcp_release(default_netif);
|
||||
dhcp_stop(default_netif);
|
||||
mem_free(default_netif);
|
||||
default_netif = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
mem_free(default_netif);
|
||||
default_netif = NULL;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int shutdown(void)
|
||||
{
|
||||
#ifdef CONFIG_LWIP
|
||||
return network_shutdown();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void list_fs(vfs_node_t* node, uint32_t depth)
|
||||
{
|
||||
|
@ -225,7 +217,45 @@ static void list_root(void) {
|
|||
|
||||
int initd(void* arg)
|
||||
{
|
||||
network_init();
|
||||
#ifdef CONFIG_LWIP
|
||||
sys_sem_t sem;
|
||||
|
||||
// Initialize lwIP modules
|
||||
if(sys_sem_new(&sem, 0) != ERR_OK)
|
||||
LWIP_ASSERT("Failed to create semaphore", 0);
|
||||
tcpip_init(tcpip_init_done, &sem);
|
||||
sys_sem_wait(&sem);
|
||||
kprintf("TCP/IP initialized.\n");
|
||||
sys_sem_free(&sem);
|
||||
|
||||
#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK))
|
||||
/* test if interface is really up */
|
||||
if (!netif_is_up(default_netif)) {
|
||||
kputs("network interface is not up\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ROCKCREEK
|
||||
int mscnt = 0;
|
||||
/* wait for ip address */
|
||||
while(default_netif && !default_netif->ip_addr.addr) {
|
||||
sys_msleep(DHCP_FINE_TIMER_MSECS);
|
||||
dhcp_fine_tmr();
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
|
||||
dhcp_coarse_tmr();
|
||||
mscnt = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// start echo and ping server
|
||||
echo_init();
|
||||
//ping_init();
|
||||
netio_init();
|
||||
#endif
|
||||
|
||||
list_root();
|
||||
test_init();
|
||||
|
||||
|
|
|
@ -94,12 +94,9 @@ int main(void)
|
|||
create_kernel_task(NULL, initd, NULL, NORMAL_PRIO);
|
||||
reschedule();
|
||||
|
||||
while(1) {
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
//icc_halt();
|
||||
#else
|
||||
while(1) {
|
||||
check_workqueues();
|
||||
HALT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
345
kernel/netio.c
345
kernel/netio.c
|
@ -1,50 +1,354 @@
|
|||
/*
|
||||
* this example is derived from the netio example of the contrib-1.4.0
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* see http://download.savannah.gnu.org/releases/lwip/
|
||||
*/
|
||||
|
||||
#include <metalsvm/stddef.h>
|
||||
#include <lwip/opt.h>
|
||||
#include <metalsvm/stdlib.h>
|
||||
#include <metalsvm/processor.h>
|
||||
|
||||
#if defined(CONFIG_LWIP)
|
||||
|
||||
#include <lwip/opt.h>
|
||||
|
||||
#if LWIP_TCP
|
||||
#include <lwip/tcp.h>
|
||||
|
||||
/*
|
||||
* This implements a netio server.
|
||||
* The client sends a command word (4 bytes) then a data length word (4 bytes).
|
||||
* If the command is "receive", the server is to consume "data length" bytes into
|
||||
* a circular buffer until the first byte is non-zero, then it is to consume
|
||||
* another command/data pair.
|
||||
* If the command is "send", the server is to send "data length" bytes from a circular
|
||||
* buffer with the first byte being zero, until "some time" and then send one final buffer with
|
||||
* the first byte being non-zero. Then it is to consume another command/data pair.
|
||||
*/
|
||||
|
||||
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
|
||||
|
||||
#if LWIP_TCP
|
||||
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
/* implementation options */
|
||||
#define NETIO_BUF_SIZE (4 * 1024)
|
||||
#define NETIO_USE_STATIC_BUF 0
|
||||
|
||||
/* NetIO server state definition */
|
||||
#define NETIO_STATE_WAIT_FOR_CMD 0
|
||||
#define NETIO_STATE_RECV_DATA 1
|
||||
#define NETIO_STATE_SEND_DATA 2
|
||||
#define NETIO_STATE_SEND_DATA_LAST 3
|
||||
#define NETIO_STATE_DONE 4
|
||||
|
||||
struct netio_state {
|
||||
u32_t state;
|
||||
u32_t cmd;
|
||||
u32_t data_len;
|
||||
u32_t cntr;
|
||||
u8_t * buf_ptr;
|
||||
u32_t buf_pos;
|
||||
u32_t first_byte;
|
||||
u64_t time_stamp;
|
||||
};
|
||||
|
||||
/* NetIO command protocol definition */
|
||||
#define NETIO_CMD_QUIT 0
|
||||
#define NETIO_CMD_C2S 1
|
||||
#define NETIO_CMD_S2C 2
|
||||
#define NETIO_CMD_RES 3
|
||||
|
||||
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
|
||||
|
||||
static void
|
||||
netio_close(void *arg, struct tcp_pcb *pcb)
|
||||
{
|
||||
err_t err;
|
||||
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
struct netio_state *ns = arg;
|
||||
ns->state = NETIO_STATE_DONE;
|
||||
tcp_recv(pcb, NULL);
|
||||
err = tcp_close(pcb);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
/* closing failed, try again later */
|
||||
tcp_recv(pcb, netio_recv);
|
||||
} else {
|
||||
/* closing succeeded */
|
||||
#if NETIO_USE_STATIC_BUF != 1
|
||||
if(ns->buf_ptr != NULL){
|
||||
mem_free(ns->buf_ptr);
|
||||
}
|
||||
#endif
|
||||
tcp_arg(pcb, NULL);
|
||||
tcp_poll(pcb, NULL, 0);
|
||||
tcp_sent(pcb, NULL);
|
||||
if (arg != NULL) {
|
||||
mem_free(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static err_t
|
||||
netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
{
|
||||
struct netio_state *ns = arg;
|
||||
u8_t * data_ptr;
|
||||
u32_t data_cntr;
|
||||
struct pbuf *q = p;
|
||||
u16_t len;
|
||||
|
||||
if (err == ERR_OK && q != NULL) {
|
||||
|
||||
while (q != NULL) {
|
||||
data_cntr = q->len;
|
||||
data_ptr = q->payload;
|
||||
while (data_cntr--) {
|
||||
if (ns->state == NETIO_STATE_DONE){
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
} else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
|
||||
if (ns->cntr < 4) {
|
||||
/* build up the CMD field */
|
||||
ns->cmd <<= 8;
|
||||
ns->cmd |= *data_ptr++;
|
||||
ns->cntr++;
|
||||
} else if (ns->cntr < 8) {
|
||||
/* build up the DATA field */
|
||||
ns->data_len <<= 8;
|
||||
ns->data_len |= *data_ptr++;
|
||||
ns->cntr++;
|
||||
|
||||
if (ns->cntr == 8) {
|
||||
/* now we have full command and data words */
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
ns->buf_ptr[0] = 0;
|
||||
if (ns->cmd == NETIO_CMD_C2S) {
|
||||
ns->state = NETIO_STATE_RECV_DATA;
|
||||
} else if (ns->cmd == NETIO_CMD_S2C) {
|
||||
ns->state = NETIO_STATE_SEND_DATA;
|
||||
/* start timer */
|
||||
ns->time_stamp = rdtsc();
|
||||
/* send first round of data */
|
||||
|
||||
len = tcp_sndbuf(pcb);
|
||||
len = LWIP_MIN(len, ns->data_len - ns->cntr);
|
||||
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
|
||||
//kprintf("data length: %d, len: %d\n", ns->data_len, len);
|
||||
|
||||
do {
|
||||
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
|
||||
if (err == ERR_MEM) {
|
||||
len /= 2;
|
||||
}
|
||||
} while ((err == ERR_MEM) && (len > 1));
|
||||
|
||||
ns->buf_pos += len;
|
||||
ns->cntr += len;
|
||||
|
||||
} else {
|
||||
/* unrecognized command, punt */
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
ns->buf_ptr[0] = 0;
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* in trouble... shouldn't be in this state! */
|
||||
kputs("netio is in trouble\n");
|
||||
}
|
||||
|
||||
} else if (ns->state == NETIO_STATE_RECV_DATA) {
|
||||
|
||||
if(ns->cntr == 0){
|
||||
/* save the first byte of this new round of data
|
||||
* this will not match ns->buf_ptr[0] in the case that
|
||||
* NETIO_BUF_SIZE is less than ns->data_len.
|
||||
*/
|
||||
ns->first_byte = *data_ptr;
|
||||
}
|
||||
|
||||
ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
|
||||
ns->cntr++;
|
||||
|
||||
if (ns->buf_pos == NETIO_BUF_SIZE) {
|
||||
/* circularize the buffer */
|
||||
ns->buf_pos = 0;
|
||||
}
|
||||
|
||||
if(ns->cntr == ns->data_len){
|
||||
ns->cntr = 0;
|
||||
if (ns->first_byte != 0) {
|
||||
/* if this last round did not start with 0,
|
||||
* go look for another command */
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->data_len = 0;
|
||||
ns->cmd = 0;
|
||||
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
|
||||
} else {
|
||||
/* stay here and wait on more data */
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ns->state == NETIO_STATE_SEND_DATA
|
||||
|| ns->state == NETIO_STATE_SEND_DATA_LAST) {
|
||||
/* I don't think this should happen... */
|
||||
} else {
|
||||
/* done / quit */
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
} /* end of ns->state condition */
|
||||
} /* end of while data still in this pbuf */
|
||||
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
if (err == ERR_OK && p != NULL) {
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
pbuf_free(p);
|
||||
|
||||
} else {
|
||||
pbuf_free(p);
|
||||
|
||||
/* error or closed by other side */
|
||||
if (p != NULL) {
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
/* close the connection */
|
||||
netio_close(ns, pcb);
|
||||
|
||||
}
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
static err_t
|
||||
netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||
{
|
||||
struct netio_state *ns = arg;
|
||||
err_t err = ERR_OK;
|
||||
|
||||
if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
|
||||
u64_t now = rdtsc();
|
||||
u64_t time = (now - ns->time_stamp) / get_cpu_frequency();
|
||||
|
||||
/* done with this round of sending */
|
||||
ns->buf_pos = 0;
|
||||
ns->cntr = 0;
|
||||
ns->buf_ptr[0] = 1;
|
||||
ns->state = NETIO_STATE_SEND_DATA_LAST;
|
||||
|
||||
kprintf("consumed time: %llu usec (%llu ticks)\n", time, now - ns->time_stamp);
|
||||
kprintf("throughput: %llu KByte/s\n", (ns->data_len * 1000000ULL) / (time*1024));
|
||||
}
|
||||
|
||||
if (err == ERR_OK && p == NULL) {
|
||||
tcp_arg(pcb, NULL);
|
||||
tcp_sent(pcb, NULL);
|
||||
tcp_recv(pcb, NULL);
|
||||
tcp_close(pcb);
|
||||
if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
|
||||
len = tcp_sndbuf(pcb);
|
||||
len = LWIP_MIN(len, ns->data_len - ns->cntr);
|
||||
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
|
||||
|
||||
if(ns->cntr < ns->data_len){
|
||||
do {
|
||||
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
|
||||
if (err == ERR_MEM) {
|
||||
len /= 2;
|
||||
}
|
||||
} while ((err == ERR_MEM) && (len > 1));
|
||||
|
||||
ns->buf_pos += len;
|
||||
if(ns->buf_pos >= NETIO_BUF_SIZE){
|
||||
ns->buf_pos = 0;
|
||||
}
|
||||
|
||||
ns->cntr += len;
|
||||
}
|
||||
}
|
||||
|
||||
if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){
|
||||
/* we have buffered up all our data to send this last round, go look for a command */
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->cntr = 0;
|
||||
ns->buf_ptr[0] = 0;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
static err_t
|
||||
netio_poll(void *arg, struct tcp_pcb *pcb)
|
||||
{
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
struct netio_state * ns = arg;
|
||||
|
||||
if(ns->state == NETIO_STATE_SEND_DATA) {
|
||||
|
||||
} else if(ns->state == NETIO_STATE_DONE){
|
||||
netio_close(ns, pcb);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
#if NETIO_USE_STATIC_BUF == 1
|
||||
static u8_t netio_buf[NETIO_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
static err_t
|
||||
netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
{
|
||||
struct netio_state * ns;
|
||||
|
||||
LWIP_UNUSED_ARG(err);
|
||||
|
||||
tcp_arg(pcb, NULL);
|
||||
tcp_sent(pcb, NULL);
|
||||
ns = mem_malloc(sizeof(struct netio_state));
|
||||
|
||||
if(ns == NULL){
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->data_len = 0;
|
||||
ns->cmd = 0;
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
#if NETIO_USE_STATIC_BUF == 1
|
||||
ns->buf_ptr = netio_buf;
|
||||
#else
|
||||
ns->buf_ptr = mem_malloc(NETIO_BUF_SIZE);
|
||||
|
||||
if(ns->buf_ptr == NULL){
|
||||
mem_free(ns);
|
||||
return ERR_MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(ns->buf_ptr, 0x00, NETIO_BUF_SIZE);
|
||||
|
||||
tcp_arg(pcb, ns);
|
||||
tcp_sent(pcb, netio_sent);
|
||||
tcp_recv(pcb, netio_recv);
|
||||
tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
|
||||
//tcp_nagle_disable(pcb);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
@ -57,6 +361,7 @@ void netio_init(void)
|
|||
pcb = tcp_listen(pcb);
|
||||
tcp_accept(pcb, netio_accept);
|
||||
}
|
||||
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#include <lwip/ip.h>
|
||||
|
||||
#if LWIP_SOCKET
|
||||
#define PING_USE_SOCKETS 1
|
||||
#define PING_USE_SOCKETS 0
|
||||
#endif
|
||||
|
||||
#if PING_USE_SOCKETS
|
||||
|
@ -102,7 +102,7 @@
|
|||
#endif
|
||||
|
||||
/* ping variables */
|
||||
static u16_t ping_seq_num;
|
||||
static u16_t ping_seq_num = 0;
|
||||
static u32_t ping_time;
|
||||
#if !PING_USE_SOCKETS
|
||||
static struct raw_pcb *ping_pcb;
|
||||
|
@ -216,7 +216,7 @@ ping_thread(void *arg)
|
|||
ping_target = PING_TARGET;
|
||||
|
||||
if (ping_send(s, &ping_target) == ERR_OK) {
|
||||
LWIP_DEBUGF( PING_DEBUG, ("ping: send on core %d to " , CORE_ID));
|
||||
LWIP_DEBUGF( PING_DEBUG, ("ping: send to "));
|
||||
ip_addr_debug_print(PING_DEBUG, &ping_target);
|
||||
LWIP_DEBUGF( PING_DEBUG, ("\n"));
|
||||
|
||||
|
@ -293,6 +293,7 @@ ping_send(struct raw_pcb *raw, ip_addr_t *addr)
|
|||
static void
|
||||
ping_timeout(void *arg)
|
||||
{
|
||||
static unsigned counter = 0;
|
||||
struct raw_pcb *pcb = (struct raw_pcb*)arg;
|
||||
ip_addr_t ping_target = PING_TARGET;
|
||||
|
||||
|
@ -300,7 +301,9 @@ ping_timeout(void *arg)
|
|||
|
||||
ping_send(pcb, &ping_target);
|
||||
|
||||
sys_timeout(PING_DELAY, ping_timeout, pcb);
|
||||
counter++;
|
||||
if (counter < 5)
|
||||
sys_timeout(PING_DELAY, ping_timeout, pcb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -314,13 +317,15 @@ ping_raw_init(void)
|
|||
sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
ping_send_now()
|
||||
ping_send_now(void)
|
||||
{
|
||||
ip_addr_t ping_target = PING_TARGET;
|
||||
LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
|
||||
ping_send(ping_pcb, &ping_target);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PING_USE_SOCKETS */
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
int ret = -EINVAL;
|
||||
va_list vl;
|
||||
|
||||
check_workqueues_rem_irq();
|
||||
check_workqueues();
|
||||
|
||||
va_start(vl, sys_nr);
|
||||
|
||||
|
|
|
@ -69,8 +69,16 @@ task_t* get_current_task(void) {
|
|||
return per_core(current_task);
|
||||
}
|
||||
|
||||
uint32_t get_highest_priority(uint32_t core_id) {
|
||||
return last_set(runqueues[core_id].prio_bitmap);
|
||||
void check_scheduling(void) {
|
||||
if (!is_irq_enabled())
|
||||
return;
|
||||
if (msb(runqueues[CORE_ID].prio_bitmap) > per_core(current_task)->prio)
|
||||
reschedule();
|
||||
}
|
||||
|
||||
uint32_t get_highest_priority(void)
|
||||
{
|
||||
return msb(runqueues[CORE_ID].prio_bitmap);
|
||||
}
|
||||
|
||||
int multitasking_init(void) {
|
||||
|
@ -1244,20 +1252,15 @@ void scheduler(void)
|
|||
}
|
||||
|
||||
runqueues[core_id].old_task = NULL; // reset old task
|
||||
prio = last_set(runqueues[core_id].prio_bitmap); // determines highest priority
|
||||
prio = msb(runqueues[core_id].prio_bitmap); // determines highest priority
|
||||
#if MAX_CORES > 1
|
||||
if (!prio) {
|
||||
if (prio >= sizeof(size_t)*8) {
|
||||
load_balancing();
|
||||
prio = last_set(runqueues[core_id].prio_bitmap); // retry...
|
||||
prio = msb(runqueues[core_id].prio_bitmap); // retry...
|
||||
}
|
||||
#endif
|
||||
|
||||
if (BUILTIN_EXPECT(prio > MAX_PRIO, 0)) {
|
||||
kprintf("Invalid priority %u by bitmap 0x%x\n", prio, runqueues[core_id].prio_bitmap);
|
||||
prio = 0;
|
||||
}
|
||||
|
||||
if (!prio) {
|
||||
if (prio >= sizeof(size_t)*8) {
|
||||
if ((curr_task->status == TASK_RUNNING) || (curr_task->status == TASK_IDLE))
|
||||
goto get_task_out;
|
||||
curr_task = per_core(current_task) = runqueues[core_id].idle;
|
||||
|
|
|
@ -167,7 +167,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void **msg, u32_t timeout)
|
|||
int err;
|
||||
|
||||
err = mailbox_ptr_fetch(&mbox->mailbox, msg, timeout);
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_arch_mbox_fetch: %d\n", err));
|
||||
//LWIP_DEBUGF(SYS_DEBUG, ("sys_arch_mbox_fetch: %d\n", err));
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
|
@ -216,7 +216,7 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
|||
int err;
|
||||
|
||||
err = mailbox_ptr_trypost(&mbox->mailbox, msg);
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: %d"\n, err));
|
||||
//LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: %d"\n, err));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ typedef uint16_t u16_t;
|
|||
typedef int16_t s16_t;
|
||||
typedef uint32_t u32_t;
|
||||
typedef int32_t s32_t;
|
||||
typedef uint64_t u64_t;
|
||||
typedef int64_t s64_t;
|
||||
|
||||
typedef size_t mem_ptr_t;
|
||||
|
||||
|
@ -70,7 +72,7 @@ typedef size_t mem_ptr_t;
|
|||
#define MEM_ALIGNMENT 4
|
||||
#define ETH_PAD_SIZE 2
|
||||
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
|
||||
/* prototypes for printf() and abort() */
|
||||
#include <metalsvm/stdio.h>
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H_
|
||||
|
||||
#include <metalsvm/stddef.h>
|
||||
|
||||
/**
|
||||
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
|
||||
* critical regions during buffer allocation, deallocation and memory
|
||||
|
@ -59,10 +61,19 @@
|
|||
*/
|
||||
#define LWIP_TCP 1
|
||||
|
||||
/**
|
||||
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
|
||||
* you might want to increase this.)
|
||||
* For the receive side, this MSS is advertised to the remote side
|
||||
* when opening a connection. For the transmit size, this MSS sets
|
||||
* an upper limit on the MSS advertised by the remote host.
|
||||
*/
|
||||
#define TCP_MSS 1460
|
||||
|
||||
/**
|
||||
* TCP_SND_BUF: TCP sender buffer space (bytes).
|
||||
*/
|
||||
#define TCP_SND_BUF (16*1024)
|
||||
#define TCP_SND_BUF (16*TCP_WND)
|
||||
|
||||
/**
|
||||
* LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only)
|
||||
|
@ -118,15 +129,6 @@
|
|||
*/
|
||||
#define DEFAULT_THREAD_PRIO NORMAL_PRIO
|
||||
|
||||
/**
|
||||
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
|
||||
* you might want to increase this.)
|
||||
* For the receive side, this MSS is advertised to the remote side
|
||||
* when opening a connection. For the transmit size, this MSS sets
|
||||
* an upper limit on the MSS advertised by the remote host.
|
||||
*/
|
||||
#define TCP_MSS 2048
|
||||
|
||||
/**
|
||||
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
|
||||
*/
|
||||
|
@ -171,12 +173,36 @@
|
|||
*/
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 0x40
|
||||
|
||||
/**
|
||||
* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
|
||||
* (requires the LWIP_TCP option)
|
||||
*/
|
||||
#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
|
||||
|
||||
// On the SCC, we have not to check incoming messages from the trusted MCPC
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
/**
|
||||
* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.
|
||||
*/
|
||||
#define CHECKSUM_CHECK_IP 0
|
||||
|
||||
/**
|
||||
* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.
|
||||
*/
|
||||
#define CHECKSUM_CHECK_UDP 0
|
||||
|
||||
/**
|
||||
* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.
|
||||
*/
|
||||
#define CHECKSUM_CHECK_TCP 0
|
||||
#endif
|
||||
|
||||
/* DEBUG options */
|
||||
#define LWIP_DEBUG 1
|
||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||
#define ETHARP_DEBUG LWIP_DBG_OFF
|
||||
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||
#define SYS_DEBUG LWIP_DBG_OFF
|
||||
#define SYS_DEBUG LWIP_DBG_ON
|
||||
#define RAW_DEBUG LWIP_DBG_OFF
|
||||
#define MEM_DEBUG LWIP_DBG_OFF
|
||||
#define IP_DEBUG LWIP_DBG_OFF
|
||||
|
|
|
@ -7,7 +7,7 @@ LDFLAGS =
|
|||
LIBNAME = libsocket.a
|
||||
ARFLAGS = ruv
|
||||
CP = cp
|
||||
OBJS = accept.o bind.o closesocket.o connect.o listen.o recv.o send.o socket.o ip_addr.o
|
||||
OBJS = accept.o bind.o closesocket.o connect.o listen.o recv.o send.o socket.o ip_addr.o gethostbyname.o #setsockopt.o getsockopt.o sendto.o select.o
|
||||
|
||||
# other implicit rules
|
||||
%.o : %.c
|
||||
|
@ -23,6 +23,7 @@ $(LIBNAME): $(OBJS) socket.h
|
|||
$(CP) socket.h $(NEWLIB)/include/sys
|
||||
$(CP) in.h $(NEWLIB)/include/netinet
|
||||
$(CP) inet.h $(NEWLIB)/include/arpa
|
||||
$(CP) netdb.h $(NEWLIB)/include
|
||||
|
||||
clean:
|
||||
$(RM) $(LIBNAME) *.o *~
|
||||
|
|
56
newlib/net/gethostbyname.c
Normal file
56
newlib/net/gethostbyname.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lanes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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 "config.h"
|
||||
#include <_ansi.h>
|
||||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
#include "syscall.h"
|
||||
|
||||
struct hostent;
|
||||
|
||||
struct hostent*
|
||||
_DEFUN (gethostbyname, (name),
|
||||
const char *name)
|
||||
{
|
||||
struct hostent* ret;
|
||||
|
||||
ret = (struct hostent*) SYSCALL1(__NR_gethostbyname, name);
|
||||
//if (ret == NULL)
|
||||
// errno = -EINVAL;
|
||||
|
||||
return ret;
|
||||
}
|
56
newlib/net/getsockopt.c
Normal file
56
newlib/net/getsockopt.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lanes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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 "config.h"
|
||||
#include <_ansi.h>
|
||||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
#include "syscall.h"
|
||||
|
||||
int
|
||||
_DEFUN (getsockopt, (s, level, optname, optval, optlen),
|
||||
int s _AND int level _AND int optname _AND void *optval _AND uint32_t optlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SYSCALL6(__NR_getsockopt, s, level, optname, optval, optlen);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -106,4 +106,4 @@ char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETINET_IN_H__ */
|
||||
#endif /* __ARPA_INET_H__ */
|
||||
|
|
67
newlib/net/netdb.h
Normal file
67
newlib/net/netdb.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lankes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The kernel of MetalSVM uses LwIP as lightweight TCP/IP stack.
|
||||
* This header defines only a small wrapper to use LwIP functions
|
||||
* from user space.
|
||||
*/
|
||||
|
||||
#ifndef __NETDB_H__
|
||||
#define __NETDB_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
#endif
|
||||
|
||||
struct hostent {
|
||||
char *h_name; /* Official name of the host. */
|
||||
char **h_aliases; /* A pointer to an array of pointers to alternative host names,
|
||||
terminated by a null pointer. */
|
||||
int h_addrtype; /* Address type. */
|
||||
int h_length; /* The length, in bytes, of the address. */
|
||||
char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
|
||||
network byte order) for the host, terminated by a null pointer. */
|
||||
#define h_addr h_addr_list[0] /* for backward compatibility */
|
||||
};
|
||||
|
||||
struct hostent *gethostbyname(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETDB_H__ */
|
58
newlib/net/select.c
Normal file
58
newlib/net/select.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lanes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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 "config.h"
|
||||
#include <_ansi.h>
|
||||
#include <_syslist.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
#include "syscall.h"
|
||||
|
||||
|
||||
int
|
||||
_DEFUN (select, (maxfdp1, readset, writeset, exceptset, timeout),
|
||||
int maxfdp1 _AND fd_set *readset _AND fd_set *writeset _AND fd_set *exceptset _AND struct timeval *timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SYSCALL6(__NR_select, maxfdp1, readset, writeset, exceptset, timeout);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
58
newlib/net/sendto.c
Normal file
58
newlib/net/sendto.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lanes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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 "config.h"
|
||||
#include <_ansi.h>
|
||||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
#include "syscall.h"
|
||||
|
||||
struct sockaddr;
|
||||
|
||||
int
|
||||
_DEFUN (sendto, (s, dataptr, size, flags, to, tolen),
|
||||
int s _AND const void *dataptr _AND size_t size _AND int flags _AND const struct sockaddr *to _AND uint32_t tolen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SYSCALL7(__NR_sendto, s, dataptr, size, flags, to, tolen);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
57
newlib/net/setsockopt.c
Normal file
57
newlib/net/setsockopt.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Stefan Lanes, Chair for Operating Systems,
|
||||
* RWTH Aachen University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Chair for Operating Systems,
|
||||
* RWTH Aachen University.
|
||||
* 4. Neither the name of the Chair for Operating Systems, RWTH Aachen 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 <COPYRIGHT HOLDER> ''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 <COPYRIGHT HOLDER> 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 "config.h"
|
||||
#include <_ansi.h>
|
||||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
#include "syscall.h"
|
||||
|
||||
|
||||
int
|
||||
_DEFUN (setsockopt, (s, level, optname, optval, optlen),
|
||||
int s _AND int level _AND int optname _AND const void *optval _AND uint32_t optlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SYSCALL6(__NR_setsockopt, s, level, optname, optval, optlen);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -311,8 +311,8 @@ int send(int s, const void *dataptr, size_t size, int flags);
|
|||
int sendto(int s, const void *dataptr, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen);
|
||||
int socket(int domain, int type, int protocol);
|
||||
//int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
// struct timeval *timeout);
|
||||
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
struct timeval *timeout);
|
||||
//int ioctl(int s, long cmd, void *argp);
|
||||
//int fcntl(int s, int cmd, int val);
|
||||
|
||||
|
|
|
@ -63,6 +63,12 @@ extern "C" {
|
|||
#define __NR_recv 21
|
||||
#define __NR_send 22
|
||||
#define __NR_socket 23
|
||||
#define __NR_getsockopt 24
|
||||
#define __NR_setsockopt 25
|
||||
#define __NR_gethostbyname 26
|
||||
#define __NR_sendto 27
|
||||
#define __NR_recvfrom 28
|
||||
#define __NR_select 29
|
||||
|
||||
#define _STR(token) #token
|
||||
#define _SYSCALLSTR(x) "int $" _STR(x) " "
|
||||
|
|
|
@ -36,7 +36,7 @@ reset_vector.bin: reset_vector.o
|
|||
ld --oformat binary -Ttext 0 -melf_i386 -o $@ $<
|
||||
|
||||
scc_bootinfo.asm: bootinfo.sh
|
||||
./bootinfo.sh 0x00400000 initrd.img 1 533 0 > scc_bootinfo.asm
|
||||
./bootinfo.sh 0x01000000 initrd.img 1 533 0 > scc_bootinfo.asm
|
||||
|
||||
scc_bootinfo.bin: scc_bootinfo.asm
|
||||
$(NASM) $(NASMFLAGS) -o $@ $<
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
0x00080000 scc_bootinfo.bin
|
||||
0x00090200 scc_setup.bin
|
||||
0x00100000 metalsvm.bin
|
||||
0x00400000 initrd.img
|
||||
0x01000000 initrd.img
|
||||
0xfffff000 reset_vector.bin
|
||||
|
|
Loading…
Add table
Reference in a new issue