⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================
//
//      src/ecos/support.c
//
//==========================================================================
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD, 
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// Portions created by Red Hat are
// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
//
// Copyright (C) 2002, 2003 Gary Thomas
// Copyright (C) 2003 Andrew Lunn
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================

//==========================================================================
//
//      ecos/support.c
//
//      eCos wrapper and support functions
//
//==========================================================================
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    gthomas, hmt
// Contributors: gthomas, hmt, andrew.lunn@ascom.ch
// Date:         2000-01-10
// Purpose:      
// Description:  
//              
//
//####DESCRIPTIONEND####
//
//==========================================================================


// Support routines, etc., used by network code

#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <net/netisr.h>

#include <cyg/infra/diag.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_if.h>
#include <cyg/infra/cyg_ass.h>

#ifdef CYGPKG_NET_INET6
#include <netinet/in.h>
#include <netinet6/in6_var.h>
#endif

#if !CYGPKG_NET_DRIVER_FRAMEWORK   // Interface
#error At least one network driver framework must be defined!
#else
#include <cyg/io/eth/netdev.h>

// Define table boundaries
CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
CYG_HAL_TABLE_BEGIN( __NET_INIT_TAB__, _Net_inits );
CYG_HAL_TABLE_END( __NET_INIT_TAB_END__, _Net_inits );
extern struct init_tab_entry __NET_INIT_TAB__[], __NET_INIT_TAB_END__;

// Used for system-wide "ticks per second"
#undef ticks
int hz = 100;
int tick = 10000;  // usec per "tick"
volatile struct timeval ktime;
int proc = 0;  // unused
int proc0 = 0;  // unused

volatile struct timeval mono_time;

// Low-level network debugging & logging
#ifdef CYGPKG_NET_FREEBSD_LOGGING
int cyg_net_log_mask = CYGPKG_NET_FREEBSD_LOGGING;
#endif

#ifdef CYGPKG_NET_INET6
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL+2048)
#else
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
#endif
static char netint_stack[STACK_SIZE];
static cyg_thread netint_thread_data;
static cyg_handle_t netint_thread_handle;

cyg_flag_t netint_flags;  
#define NETISR_ANY 0xFFFFFFFF  // Any possible bit...

extern void cyg_test_exit(void);  // TEMP
void
cyg_panic(const char *msg, ...)
{
    cyg_uint32 old_ints;
    CYG_FAIL( msg );
    HAL_DISABLE_INTERRUPTS(old_ints);
    diag_printf("PANIC: %s\n", msg);
    cyg_test_exit();  // FIXME
}

#define NET_MEMPOOL_SIZE  roundup(CYGPKG_NET_MEM_USAGE/4,MSIZE)
#define NET_MBUFS_SIZE    roundup(CYGPKG_NET_MEM_USAGE/4,MSIZE)
#define NET_CLUSTERS_SIZE roundup(CYGPKG_NET_MEM_USAGE/2,MCLBYTES)

static unsigned char net_mempool_area[NET_MEMPOOL_SIZE];
static cyg_mempool_var net_mem_pool;
static cyg_handle_t    net_mem;
static unsigned char net_mbufs_area[NET_MBUFS_SIZE];
static cyg_mempool_fix net_mbufs_pool;
static cyg_handle_t    net_mbufs;
static unsigned char net_clusters_area[NET_CLUSTERS_SIZE];
static cyg_mempool_fix net_clusters_pool;
static cyg_handle_t    net_clusters;
static char            net_clusters_refcnt[(NET_CLUSTERS_SIZE/MCLBYTES)+1];
int nmbclusters = (NET_CLUSTERS_SIZE/MCLBYTES);

#ifdef CYGDBG_NET_TIMING_STATS
static struct net_stats  stats_malloc, stats_free, 
    stats_memcpy, stats_memset,
    stats_mbuf_alloc, stats_mbuf_free, stats_cluster_alloc;
extern struct net_stats stats_in_cksum;

// Display a number of ticks as microseconds
// Note: for improved calculation significance, values are kept in ticks*1000
static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
static long ns_per_system_clock;

static void
show_ticks_in_us(cyg_uint32 ticks)
{
    long long ns;
    ns_per_system_clock = 1000000/rtc_resolution[1];
    ns = (ns_per_system_clock * ((long long)ticks * 1000)) / 
        CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
    ns += 5;  // for rounding to .01us
    diag_printf("%7d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
}

void
show_net_stats(struct net_stats *stats, const char *title)
{
    int ave;
    ave = stats->total_time / stats->count;
    diag_printf("%s:\n", title);
    diag_printf("  count: %6d", stats->count);
    diag_printf(", min: ");
    show_ticks_in_us(stats->min_time);
    diag_printf(", max: ");
    show_ticks_in_us(stats->max_time);
    diag_printf(", total: ");
    show_ticks_in_us(stats->total_time);
    diag_printf(", ave: ");
    show_ticks_in_us(ave);
    diag_printf("\n");
    // Reset stats
    memset(stats, 0, sizeof(*stats));
}

void
show_net_times(void)
{
    show_net_stats(&stats_malloc,        "Net malloc");
    show_net_stats(&stats_free,          "Net free");
    show_net_stats(&stats_mbuf_alloc,    "Mbuf alloc");
    show_net_stats(&stats_mbuf_free,     "Mbuf free");
    show_net_stats(&stats_cluster_alloc, "Cluster alloc");
    show_net_stats(&stats_in_cksum,      "Checksum");
    show_net_stats(&stats_memcpy,        "Net memcpy");
    show_net_stats(&stats_memset,        "Net memset");
}
#endif /* CYGDBG_NET_TIMING_STATS */ 

void *
cyg_net_malloc(u_long size, int type, int flags)
{
    void *res;

    START_STATS();
    log(LOG_MDEBUG, "Net malloc[%d] = ", size);
    if (flags & M_NOWAIT) {
        res = cyg_mempool_var_try_alloc(net_mem, size);
    } else {
        res = cyg_mempool_var_alloc(net_mem, size);
    }
    if ((flags & M_ZERO) && res) {
      memset(res,0,size);
    }
    FINISH_STATS(stats_malloc);
    log(LOG_MDEBUG, "%p\n", res);
    return (res);
}

void 
cyg_net_free(caddr_t addr, int type)
{
    START_STATS();
    cyg_mempool_var_free(net_mem, addr);
    FINISH_STATS(stats_free);
}

#ifdef CYGDBG_NET_SHOW_MBUFS

struct mbuf *mbinfo[300];

void cyg_net_show_mbufs(void)
{
    int i;
    diag_printf(" MBUF   : TYPE FLGS     DATA[LEN]   NEXT    NEXTPKT\n");
    for( i = 0; i < 300; i++ )
    {
        struct mbuf *m = mbinfo[i];
        char *type;
        if( m == 0 ) continue;

        switch( m->m_hdr.mh_type )
        {
        case MT_FREE: type="FREE"; break;
        case MT_DATA: type="DATA"; break;
        case MT_HEADER: type="HEADER"; break;
        case MT_SONAME: type="SONAME"; break;
        case MT_FTABLE: type="FTABLE"; break;
        case MT_CONTROL: type="CONTROL"; break;
        case MT_OOBDATA: type="OOBDATA"; break;
        default: type="UNKNOWN"; break;
        }

        diag_printf("%08x: %s %04x %08x[%03d] %08x %08x\n",
                    m, type,
                    m->m_hdr.mh_flags,
                    m->m_hdr.mh_data,
                    m->m_hdr.mh_len,
                    m->m_hdr.mh_next,
                    m->m_hdr.mh_nextpkt);
    }
    diag_printf(" MBUF   : TYPE FLGS     DATA[LEN]   NEXT    NEXTPKT\n");    
}

#endif

void *
cyg_net_mbuf_alloc(void)
{
    void *res;    

    START_STATS();
    log(LOG_MDEBUG, "Alloc mbuf = ");
    res = cyg_mempool_fix_try_alloc(net_mbufs);
FINISH_STATS(stats_mbuf_alloc);
#ifdef CYGDBG_NET_SHOW_MBUFS    
    {
        int i;
        for( i = 0; i < (sizeof(mbinfo)/sizeof(mbinfo[0])); i++ )
            if( mbinfo[i] == 0 )
            {
                mbinfo[i] = (struct mbuf *)res;
                break;
            }
    }
#endif
    // Check that this nastiness works OK
    CYG_ASSERT( dtom(res) == res, "dtom failed, base of mbuf" );
    CYG_ASSERT( dtom((char *)res + MSIZE/2) == res, "dtom failed, mid mbuf" );
    log(LOG_MDEBUG, "%p\n", res);
    return (res);
}

void *
cyg_net_cluster_alloc(void)
{
    void *res;

    START_STATS();
    log(LOG_MDEBUG, "Allocate cluster = ");
    res = cyg_mempool_fix_try_alloc(net_clusters);
    FINISH_STATS(stats_cluster_alloc);
    log(LOG_MDEBUG, "%p\n", res);
    return res;
}

static struct vm_zone *vm_zones = (struct vm_zone *)NULL;

vm_zone_t 
zinit(char *name, int size, int nentries, int flags, int zalloc)
{
    void *res;
    vm_zone_t zone = (vm_zone_t)0;
    elem *p;

    log(LOG_MDEBUG, "zinit '%s', size: %d, num: %d, flags: %d, alloc: %d\n", 
        name, size, nentries, flags, zalloc);
    res = cyg_mempool_var_try_alloc(net_mem, sizeof(struct vm_zone));
    if (res) {
        zone = (vm_zone_t)res;
        res = cyg_mempool_var_try_alloc(net_mem, size*nentries);
    }
    if (!res) {
        log(LOG_MDEBUG, "Can't allocate memory for %s\n", name);
        panic("zinit: Out of memory\n");
    }
    p = (elem *)res;
    zone->pool = (elem *)0;
    zone->elem_size = size;
    zone->name = name;
    zone->free = zone->total = nentries;
    zone->next = vm_zones;
    zone->alloc_tries = zone->alloc_fails = zone->alloc_frees = 0;
    vm_zones = zone;
    while (nentries-- > 0) {
        p->next = zone->pool;
        zone->pool = p;
        p = (elem *)((char *)p + size);
    }
    p = zone->pool;
#if 0
    while (p) {
        log(LOG_MDEBUG, "p: %p, next: %p\n", p, p->next);
        p = p->next;
    }
#endif
    return zone;
}

void *    
zalloci(vm_zone_t zone)
{
    elem *p;

    p = zone->pool;
    zone->alloc_tries++;
    if (p) {
        zone->pool = p->next;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -