Merge branch 'master' into ohligs

Conflicts:
	kernel/init.c
	kernel/tests.c
This commit is contained in:
Marian Ohligs 2011-09-09 21:23:15 +02:00
commit e572d1c502
32 changed files with 1029 additions and 170 deletions

View file

@ -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

View file

@ -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
*/

View file

@ -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();
}

View file

@ -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
/*

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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();

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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>

View file

@ -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

View file

@ -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 *~

View 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
View 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;
}

View file

@ -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
View 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
View 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
View 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
View 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;
}

View file

@ -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);

View file

@ -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) " "

View file

@ -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 $@ $<

View file

@ -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