/* * Copyright 2010 Stefan Lankes, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of MetalSVM. */ #include #include #include #include #include #include #include #include #ifdef CONFIG_LWIP #include #include #include #include #include #include #include #include #include #endif #include #include #ifdef CONFIG_ROCKCREEK #include #include #endif void echo_init(void); void ping_init(void); static volatile int done = 0; /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. */ extern const void bss_start; extern const void bss_end; int lowlevel_init(void) { // initialize .bss section memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); koutput_init(); //kprintf("Now, the BSS section (0x%x - 0x%x) is initialized.\n", (size_t) &bss_start, (size_t) &bss_end); return 0; } #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static tid_t netid; int STDCALL network_task(void* arg) { struct netif netif; struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; kputs("Network task is started\n"); #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(&netmask, 255,255,255,0); /* Bring up the network interface */ if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, ethernet_input)) { #else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 0,0,0,0); IP4_ADDR(&netmask, 0,0,0,0); /* Bring up the network interface */ if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, ethernet_input)) { #endif kputs("Unable to add network interface\n"); return -ENXIO; } netif_set_default(&netif); if (netif_is_up(&netif)) { kputs("Network interface is not up\n"); return -EIO; } #ifndef CONFIG_ROCKCREEK kprintf("Starting DHCPCD...\n"); dhcp_start(&netif); /* wait for ip address */ while(!netif.ip_addr.addr) { rtl8139if_wait(&netif, 1); udelay(500000); } #endif // start echo and ping server echo_init(); ping_init(); while(!done) { #ifdef CONFIG_PCI rtl8139if_wait(&netif, 0); #elif defined(CONFIG_ROCKCREEK) rckemacif_wait(&netif, 0); #endif } #ifndef CONFIG_ROCKCREEK dhcp_release(&netif); dhcp_stop(&netif); #endif return 0; } #endif int network_shutdown(void) { done = 1; return 0; } int network_init(void) { #if defined(CONFIG_LWIP) // Initialize lwIP modules lwip_init(); #endif #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) return create_kernel_task(&netid, network_task, NULL); #else return 0; #endif }