coldfire port.patch #872 from David Haas

This commit is contained in:
jani 2003-01-18 18:47:22 +00:00
parent 1cb0c2930a
commit 2b84c23ea3
15 changed files with 4096 additions and 0 deletions

View File

@ -14,6 +14,9 @@ unix/ - Architectural files for testing on unix-like systems
v2pro/ - Architectural files for the Xilinx Virtex-II PRO device with
embedded PowerPC 405 Processor. Supports lwIP Raw API only.
(requires V2PDK - http://www.xilinx.com/ise/vii_pro/kit.htm)
coldfire/ - Architectural files for Motorola Coldfire 5272 CPU running
under Nucleus OS. Supports DMA and ISRs in ethernet driver.
Each subdirectory (may) also include:

231
ports/coldfire/README Normal file
View File

@ -0,0 +1,231 @@
### README --- c:/cygwin/home/dhaas/work/cfimage/lwip/arch/coldfire/
##
## Author: dhaas@alum.rpi.edu
These files are a port of lwip to coldfire (specifically the MCF5272 with
on-board FEC) under the Nucleus OS. Nucleus is pretty generic so it should be
fairly easy to port this to any other embedded OS. Nucleus memory managment
is not used. It is assumed you have a working malloc (which at least
long-word aligns memory).
The compiler used was Diab 4.3b. You will almost certainly need to change
cc.h for your compiler.
IMPORTANT NOTE: If you use the fec driver for a different processor which has
a data cache you will need to make sure the buffer descriptors and memory
used for pbufs are not in a cachable area. Otherwise the fec driver is
guarrenteed to malfunction. The 5272 which this was written for does not
support data cache so it did not matter and malloc was used.
I have not released a proj directory, since my system is probably very
different than anyone trying to use this code. However my lwipopts file might
look a little different, and I reproduce that here:
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#define NO_SYS 0
/*#define LWIP_EVENT_API 0*/
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 65000
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 16
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 4
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 5
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 16
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 6
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 10
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#define MEMP_NUM_API_MSG 16
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG 16
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 3
/* These two control is reclaimer functions should be compiled
in. Should always be turned on (1). */
#define MEM_RECLAIM 1
#define MEMP_RECLAIM 1
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 128
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 1024
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 16
/* SYS_ISR_PROT: Define this macro if pbuf functions are called from
an ISR and you need extra (and faster) critical region protection. */
#define SYS_ISR_PROT 1
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 128
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 256
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
/* TCP receive window. */
#define TCP_WND 1024
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
#define TCP_SNDLOWAT TCP_SND_BUF/2
/* ---------- ARP options ---------- */
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1
/**
* - If enabled, cache entries are generated for every kind of ARP traffic or
* broadcast IP traffic. This enhances behaviour for sending to a dynamic set
* of hosts, for example if acting as a gateway.
* - If disabled, cache entries are generated only for IP destination addresses
* in use by lwIP or applications. This enhances performance if sending to a small,
* reasonably static number of hosts. Typically for embedded devices.
*/
#define ETHARP_ALWAYS_INSERT 0
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 0
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS 1
/* IP reassembly and segmentation.These are orthogonal even
* if they both deal with IP fragments */
#define IP_REASSEMBLY 1
#define IP_FRAG 1
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK 1
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define UDP_TTL 255
/* ---------- Statistics options ---------- */
#define STATS
#ifdef STATS
#define LINK_STATS
#define IP_STATS
#define ICMP_STATS
#define UDP_STATS
#define TCP_STATS
#define MEM_STATS
#define MEMP_STATS
#define PBUF_STATS
#define SYS_STATS
#endif /* STATS */
#define LWIP_COMPAT_SOCKETS
#endif /* __LWIPOPTS_H__ */

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2001-2003, Swedish Institute of Computer Science.
* 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. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: cc.h,v 1.1 2003/01/18 18:47:22 jani Exp $
*/
#ifndef __CC_H__
#define __CC_H__
#include <types.h>
// typedef unsigned char u8_t;
// typedef signed char s8_t;
// typedef unsigned short u16_t;
// typedef signed short s16_t;
// typedef unsigned long u32_t;
// typedef signed long s32_t;
typedef u32_t mem_ptr_t;
#define PACK_STRUCT_BEGIN #pragma pack(1,1,0)
#define PACK_STRUCT_STRUCT
#define ALIGN_STRUCT_8_BEGIN #pragma pack(1,8,0)
#define ALIGN_STRUCT_END #pragma pack()
#define PACK_STRUCT_END #pragma pack()
#define PACK_STRUCT_FIELD(x) x
#define _SYS_TYPES_FD_SET
#define NBBY 8 /* number of bits in a byte */
#ifndef FD_SETSIZE
#define FD_SETSIZE 64
#endif /* FD_SETSIZE */
typedef long fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x,y) (((x)+((y)-1))/(y))
#endif /* howmany */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
#define FD_ZERO(p) do { \
size_t __i; \
char *__tmp = (char *)p; \
for (__i = 0; __i < sizeof (*(p)); ++__i) \
*__tmp++ = 0; \
} while (0)
#endif /* __CC_H__ */

View File

@ -0,0 +1,43 @@
/* @(#)cpu.h
* Copyright (c) 2001-2003, Swedish Institute of Computer Science.
* 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. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
*
* Author: David Haas <dhaas@alum.rpi.edu>
*
*/
#ifndef _CPU_H
#define _CPU_H 1
#define BYTE_ORDER BIG_ENDIAN
#define IMM_ADDRESS (0x10000000)
#define FEC_LEVEL 4
#endif /* _CPU_H */

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* 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. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
*
* Author: David Haas <dhaas@alum.rpi.edu>
*
* $Id:
*/
#ifndef __ERRNO_H__
#define __ERRNO_H__
/* This can be used to test whether errno is implemented */
#define ERRNO
#define errno (*sys_arch_errno())
/* Error numbers */
#define EBADF 9 /* Bad file number */
#define EINVAL 22 /* Invalid argument */
#define ENOBUFS 105 /* No buffer space available */
#define EWOULDBLOCK 40 /* We would have blocked if this was'nt non-blocking i/o */
#endif

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2001-2003, Swedish Institute of Computer Science.
* 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. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lib.h,v 1.1 2003/01/18 18:47:22 jani Exp $
*/
#ifndef __LIB_H__
#define __LIB_H__
#include <string.h>
#endif /* __LIB_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View File

@ -0,0 +1,69 @@
/* @(#)sys_arch.h
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: David Haas
*
*/
#ifndef _SYS_ARCH_H
#define _SYS_ARCH_H 1
#include <nucleus.h>
#include <stdlib.h>
#include "netif/etharp.h"
#define SYS_MBOX_NULL NULL
#define SYS_SEM_NULL NULL
/* sockets needs this definition. include time.h if this is a unix system */
struct timeval {
long tv_sec;
long tv_usec;
};
typedef NU_SEMAPHORE * sys_sem_t;
typedef NU_QUEUE * sys_mbox_t;
typedef NU_TASK * sys_thread_t;
/* Functions specific to Coldfire/Nucleus */
void
sys_setvect(u32_t vector, void (*isr_function)(void), void (*dis_funct)(void));
u32_t
sys_disable_interrupts(void);
void
sys_restore_interrupts(u32_t old_level);
void
sys_get_eth_addr(struct eth_addr *eth_addr);
int *
sys_arch_errno(void);
#include "arch/errno.h"
#endif /* _SYS_ARCH_H */

View File

@ -0,0 +1,44 @@
/* @(#)5272fec.h
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Purpose: MCF5272 fec ethernet driver
*
* Author: David Haas
*
*/
#ifndef _5272FEC_H
#define _5272FEC_H 1
void
mcf5272fecif_init(struct netif *netif);
#endif /* _5272FEC_H */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_TCPDUMP_H__
#define __NETIF_TCPDUMP_H__
#include "lwip/pbuf.h"
void tcpdump(struct pbuf *p);
#endif /* __NETIF_TCPDUMP_H__ */

View File

@ -0,0 +1,787 @@
/*
* Copyright (c) 2001-2003, Swedish Institute of Computer Science.
* 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. Neither the name of the Institute 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 THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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.
*
* Author: David Haas dhaas@alum.rpi.edu
*
*/
/* This is an ethernet driver for the internal fec in the Coldfire MCF5272.
The driver has been written to use ISRs for Receive Frame and Transmit Frame
Complete.
*/
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "netif/etharp.h"
#include "arch/mcf5272.h"
/* Sizing the descriptor rings will depend upon how many pbufs you have available
* and how big they are. Also on how many frames you might want to input before dropping
* frames. Generally it is a good idea to buffer one tcp window. This means that
* you won't get a tcp retransmit and your tcp transmissions will be reasonably fast.
*/
#define NUM_RXBDS 64 // Number of receive descriptor rings
#define NUM_TXBDS 32 // Number of transmit descriptor rings
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'
/* Define interface MTU size. We set this to 1518, since this is the max
Size of an ethernet frame without VLAN support. */
#define MTU_FEC 1518
PACK_STRUCT_BEGIN
struct rxbd
{
u16_t flags;
u16_t data_len;
u8_t *p_buf;
};
PACK_STRUCT_END
typedef struct rxbd rxbd_t;
PACK_STRUCT_BEGIN
struct txbd
{
u16_t flags;
u16_t data_len;
u8_t *p_buf;
};
PACK_STRUCT_END
typedef struct txbd txbd_t;
ALIGN_STRUCT_8_BEGIN
struct mcf5272if
{
rxbd_t rxbd_a[NUM_RXBDS]; // Rx descriptor ring. Must be aligned to double-word
txbd_t txbd_a[NUM_TXBDS]; // Tx descriptor ring. Must be aligned to double-word
struct pbuf *rx_pbuf_a[NUM_RXBDS]; // Array of pbufs corresponding to payloads in rx desc ring.
struct pbuf *tx_pbuf_a[NUM_TXBDS]; // Array of pbufs corresponding to payloads in tx desc ring.
unsigned int rx_remove; // Index that driver will remove next rx frame from.
unsigned int rx_insert; // Index that driver will insert next empty rx buffer.
unsigned int tx_insert; // Index that driver will insert next tx frame to.
unsigned int tx_remove; // Index that driver will clean up next tx buffer.
unsigned int tx_free; // Number of free transmit descriptors.
unsigned int rx_buf_len; // number of bytes in a rx buffer (that we can use).
MCF5272_IMM *imm; // imm address. All register accesses use this as base.
struct eth_addr *ethaddr;
struct netif *netif;
};
ALIGN_STRUCT_END
typedef struct mcf5272if mcf5272if_t;
#define INC_RX_BD_INDEX(idx) do { if (++idx >= NUM_RXBDS) idx = 0; } while (0)
#define INC_TX_BD_INDEX(idx) do { if (++idx >= NUM_TXBDS) idx = 0; } while (0)
#define DEC_TX_BD_INDEX(idx) do { if (idx-- == 0) idx = NUM_TXBDS-1; } while (0)
static mcf5272if_t *mcf5272if;
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
u32_t phy;
typedef struct mcf5272if mcf5272if_t;
/*-----------------------------------------------------------------------------------*/
static void
fill_rx_ring(mcf5272if_t *mcf5272)
{
struct pbuf *p;
struct rxbd *p_rxbd;
int i = mcf5272->rx_insert;
void *new_payload;
u32_t u_p_pay;
/* Try and fill as many receive buffers as we can */
while (mcf5272->rx_pbuf_a[i] == 0)
{
p = pbuf_alloc(PBUF_RAW, (u16_t) mcf5272->rx_buf_len, PBUF_POOL);
if (p == 0)
/* No pbufs, so can't refill ring */
return;
/* Align payload start to be divisible by 16 as required by HW */
u_p_pay = (u32_t) p->payload;
new_payload = p->payload = (void *) (((u_p_pay + 15) / 16) * 16);
mcf5272->rx_pbuf_a[i] = p;
p_rxbd = &mcf5272->rxbd_a[i];
p_rxbd->p_buf = (u8_t *) new_payload;
p_rxbd->flags = (p_rxbd->flags & MCF5272_FEC_RX_BD_W) | MCF5272_FEC_RX_BD_E;
INC_RX_BD_INDEX(mcf5272->rx_insert);
i = mcf5272->rx_insert;
}
}
/*-----------------------------------------------------------------------------------*/
static void
enable_fec(mcf5272if_t *mcf5272)
{
MCF5272_IMM *imm = mcf5272->imm;
int i;
/* Initialize empty tx descriptor ring */
for(i = 0; i < NUM_TXBDS-1; i++)
mcf5272->txbd_a[i].flags = 0;
/* Set wrap bit for last descriptor */
mcf5272->txbd_a[i].flags = MCF5272_FEC_TX_BD_W;
/* initialize tx indexes */
mcf5272->tx_remove = mcf5272->tx_insert = 0;
mcf5272->tx_free = NUM_TXBDS;
/* Initialize empty rx descriptor ring */
for (i = 0; i < NUM_RXBDS-1; i++)
mcf5272->rxbd_a[i].flags = 0;
/* Set wrap bit for last descriptor */
mcf5272->rxbd_a[i].flags = MCF5272_FEC_RX_BD_W;
/* Initialize rx indexes */
mcf5272->rx_remove = mcf5272->rx_insert = 0;
/* Fill receive descriptor ring */
fill_rx_ring(mcf5272);
/* Enable FEC */
MCF5272_WR_FEC_ECR(imm, (MCF5272_FEC_ECR_ETHER_EN));// | 0x2000000));
/* Indicate that there have been empty receive buffers produced */
MCF5272_WR_FEC_RDAR(imm,1);
}
/*-----------------------------------------------------------------------------------*/
static void
disable_fec(mcf5272if_t *mcf5272)
{
MCF5272_IMM *imm = mcf5272->imm;
int i;
u32_t value;
u32_t old_level;
/* We need to disable interrupts here, It is important when dealing with shared
registers. */
old_level = sys_disable_interrupts();
/* First disable the FEC interrupts. Do it in the appropriate ICR register. */
value = MCF5272_RD_SIM_ICR3(imm);
MCF5272_WR_SIM_ICR3(imm, (value & ~(MCF5272_SIM_ICR_ERX_IL(7) |
MCF5272_SIM_ICR_ETX_IL(7) |
MCF5272_SIM_ICR_ENTC_IL(7))));
/* Now we can restore interrupts. This is because we can assume that
* we are single threaded here (only 1 thread will be calling disable_fec
* for THIS interface). */
sys_restore_interrupts(old_level);
/* Release all buffers attached to the descriptors. Since the driver
* ALWAYS zeros the pbuf array locations and descriptors when buffers are
* removed, we know we just have to free any non-zero descriptors */
for (i = 0; i < NUM_RXBDS; i++)
if (mcf5272->rx_pbuf_a[i])
{
pbuf_free(mcf5272->rx_pbuf_a[i]);
mcf5272->rx_pbuf_a[i] = 0;
mcf5272->rxbd_a->p_buf = 0;
}
for (i = 0; i < NUM_TXBDS; i++)
if (mcf5272->tx_pbuf_a[i])
{
pbuf_free(mcf5272->tx_pbuf_a[i]);
mcf5272->tx_pbuf_a[i] = 0;
mcf5272->txbd_a->p_buf = 0;
}
/* Reset the FEC - equivalent to a hard reset */
MCF5272_WR_FEC_ECR(imm,MCF5272_FEC_ECR_RESET);
/* Wait for the reset sequence to complete, it should take about 16 clock cycles */
i = 0;
while (MCF5272_RD_FEC_ECR(imm) & MCF5272_FEC_ECR_RESET)
{
if (++i > 100)
abort();
}
/* Disable all FEC interrupts by clearing the IMR register */
MCF5272_WR_FEC_IMR(imm,0);
/* Clear any interrupts by setting all bits in the EIR register */
MCF5272_WR_FEC_EIR(imm,0xFFFFFFFF);
}
/*-----------------------------------------------------------------------------------*
* Function called by receive LISR to disable fec tx interrupt
*-----------------------------------------------------------------------------------*/
static void
mcf5272_dis_tx_int(void)
{
mcf5272if_t *mcf5272 = mcf5272if;
MCF5272_IMM *imm = mcf5272->imm;
u32_t value;
value = MCF5272_RD_FEC_IMR(imm);
/* Clear rx interrupt bit */
MCF5272_WR_FEC_IMR(imm, (value & ~MCF5272_FEC_IMR_TXFEN));
return;
}
/*-----------------------------------------------------------------------------------*
*-----------------------------------------------------------------------------------*/
static void
mcf5272fec_tx_cleanup(void)
{
struct pbuf *p;
mcf5272if_t *mcf5272 = mcf5272if;
MCF5272_IMM *imm = mcf5272->imm;
u32_t value;
u32_t old_level;
unsigned int tx_remove_sof;
unsigned int tx_remove_eof;
unsigned int i;
u16_t flags;
tx_remove_sof = tx_remove_eof = mcf5272->tx_remove;
/* Loop, looking for completed buffers at eof */
while ((((flags = mcf5272->txbd_a[tx_remove_eof].flags) & MCF5272_FEC_TX_BD_R) == 0) &&
(mcf5272->tx_pbuf_a[tx_remove_eof] != 0))
{
/* See if this is last buffer in frame */
if ((flags & MCF5272_FEC_TX_BD_L) != 0)
{
i = tx_remove_eof;
/* This frame is complete. Take the frame off backwards */
do
{
p = mcf5272->tx_pbuf_a[i];
mcf5272->tx_pbuf_a[i] = 0;
mcf5272->txbd_a[i].p_buf = 0;
mcf5272->tx_free++;
if (i != tx_remove_sof)
DEC_TX_BD_INDEX(i);
else
break;
} while (1);
pbuf_free(p); // Will be head of chain
/* Look at next descriptor */
INC_TX_BD_INDEX(tx_remove_eof);
tx_remove_sof = tx_remove_eof;
}
else
INC_TX_BD_INDEX(tx_remove_eof);
}
mcf5272->tx_remove = tx_remove_eof;
/* clear interrupt status for tx interrupt */
old_level = sys_disable_interrupts();
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_EIR_TXF);
value = MCF5272_RD_FEC_IMR(imm);
/* Set tx interrupt bit again */
MCF5272_WR_FEC_IMR(imm, (value | MCF5272_FEC_IMR_TXFEN));
/* Now we can re-enable higher priority interrupts again */
sys_restore_interrupts(old_level);
}
/*-----------------------------------------------------------------------------------*
void low_level_output(mcf5272if_t *mcf5272, struct pbuf *p)
Output pbuf chain to hardware. It is assumed that there is a complete and correct
ethernet frame in p. The only buffering we have in this system is in the
hardware descriptor ring. If there is no room on the ring, then drop the frame.
*-----------------------------------------------------------------------------------*/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
mcf5272if_t *mcf5272 = netif->state;
MCF5272_IMM *imm = mcf5272->imm;
int num_desc;
int num_free;
unsigned int tx_insert_sof, tx_insert_eof;
unsigned int i;
u32_t old_level;
/* Interrupts are disabled through this whole thing to support multi-threading
* transmit calls. Also this function might be called from an ISR. */
old_level = sys_disable_interrupts();
/* Determine number of descriptors needed */
num_desc = pbuf_clen(p);
if (num_desc > mcf5272->tx_free)
{
/* Drop the frame, we have no place to put it */
pbuf_free(p);
#ifdef LINK_STATS
lwip_stats.link.memerr++;
#endif
sys_restore_interrupts(old_level);
return ERR_MEM;
} else {
/* Increment use count on pbuf */
pbuf_ref(p);
/* Put buffers on descriptor ring, but don't mark them as ready yet */
tx_insert_eof = tx_insert_sof = mcf5272->tx_insert;
q = p;
do
{
mcf5272->tx_free--;
mcf5272->tx_pbuf_a[tx_insert_eof] = q;
mcf5272->txbd_a[tx_insert_eof].p_buf = q->payload;
mcf5272->txbd_a[tx_insert_eof].data_len = q->len;
q = q->next;
if (q)
INC_TX_BD_INDEX(tx_insert_eof);
} while (q);
/* Go backwards through descriptor ring setting flags */
i = tx_insert_eof;
do
{
mcf5272->txbd_a[i].flags = (u16_t) (MCF5272_FEC_TX_BD_R |
(mcf5272->txbd_a[i].flags & MCF5272_FEC_TX_BD_W) |
((i == tx_insert_eof) ? (MCF5272_FEC_TX_BD_L | MCF5272_FEC_TX_BD_TC) : 0));
if (i != tx_insert_sof)
DEC_TX_BD_INDEX(i);
else
break;
} while (1);
INC_TX_BD_INDEX(tx_insert_eof);
mcf5272->tx_insert = tx_insert_eof;
#ifdef LINK_STATS
lwip_stats.link.xmit++;
#endif
/* Indicate that there has been a transmit buffer produced */
MCF5272_WR_FEC_TDAR(imm,1);
sys_restore_interrupts(old_level);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actuall transmission of the packet.
*
*/
/*-----------------------------------------------------------------------------------*/
static err_t
mcf5272fecif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
p = etharp_output(netif, ipaddr, p);
if(p != NULL) {
low_level_output(netif, p);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
eth_input(struct pbuf *p, struct netif *netif)
{
/* Ethernet protocol layer */
struct eth_hdr *ethhdr;
mcf5272if_t *mcf5272 = netif->state;
struct pbuf *q = NULL;
ethhdr = p->payload;
switch(htons(ethhdr->type)) {
case ETHTYPE_IP:
q = etharp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case ETHTYPE_ARP:
q = etharp_arp_input(netif, mcf5272->ethaddr, p);
break;
default:
pbuf_free(p);
break;
}
if(q != NULL) {
low_level_output(netif, q);
pbuf_free(q);
}
}
/*-----------------------------------------------------------------------------------*/
static void
arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/*-----------------------------------------------------------------------------------*
* Function called by receive LISR to disable fec rx interrupt
*-----------------------------------------------------------------------------------*/
static void
mcf5272_dis_rx_int(void)
{
mcf5272if_t *mcf5272 = mcf5272if;
MCF5272_IMM *imm = mcf5272->imm;
u32_t value;
value = MCF5272_RD_FEC_IMR(imm);
/* Clear rx interrupt bit */
MCF5272_WR_FEC_IMR(imm, (value & ~MCF5272_FEC_IMR_RXFEN));
return;
}
/*-----------------------------------------------------------------------------------*/
static void
mcf5272fec_rx(void)
{
/* This is the receive ISR. It is written to be a high-level ISR. */
u32_t old_level;
mcf5272if_t *mcf5272 = mcf5272if;
MCF5272_IMM *imm = mcf5272->imm;
u32_t value;
u16_t flags;
unsigned int rx_remove_sof;
unsigned int rx_remove_eof;
struct pbuf *p;
rx_remove_sof = rx_remove_eof = mcf5272->rx_remove;
/* Loop, looking for filled buffers at eof */
while ((((flags = mcf5272->rxbd_a[rx_remove_eof].flags) & MCF5272_FEC_RX_BD_E) == 0) &&
(mcf5272->rx_pbuf_a[rx_remove_eof] != 0))
{
/* See if this is last buffer in frame */
if ((flags & MCF5272_FEC_RX_BD_L) != 0)
{
/* This frame is ready to go. Start at first descriptor in frame. */
p = 0;
do
{
/* Adjust pbuf length if this is last buffer in frame */
if (rx_remove_sof == rx_remove_eof)
{
mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len =
mcf5272->rx_pbuf_a[rx_remove_sof]->len = (u16_t)
(mcf5272->rxbd_a[rx_remove_sof].data_len - (p ? p->tot_len : 0));
}
else
mcf5272->rx_pbuf_a[rx_remove_sof]->len =
mcf5272->rx_pbuf_a[rx_remove_sof]->tot_len = mcf5272->rxbd_a[rx_remove_sof].data_len;
/* Chain pbuf */
if (p == 0)
{
p = mcf5272->rx_pbuf_a[rx_remove_sof]; // First in chain
p->tot_len = p->len; // Important since len might have changed
}
else
pbuf_chain(p, mcf5272->rx_pbuf_a[rx_remove_sof]);
/* Clear pointer to mark descriptor as free */
mcf5272->rx_pbuf_a[rx_remove_sof] = 0;
mcf5272->rxbd_a[rx_remove_sof].p_buf = 0;
if (rx_remove_sof != rx_remove_eof)
INC_RX_BD_INDEX(rx_remove_sof);
else
break;
} while (1);
INC_RX_BD_INDEX(rx_remove_sof);
/* Check error status of frame */
if (flags & (MCF5272_FEC_RX_BD_LG |
MCF5272_FEC_RX_BD_NO |
MCF5272_FEC_RX_BD_CR |
MCF5272_FEC_RX_BD_OV))
{
#ifdef LINK_STATS
lwip_stats.link.drop++;
if (flags & MCF5272_FEC_RX_BD_LG)
lwip_stats.link.lenerr++; //Jumbo gram
else
if (flags & (MCF5272_FEC_RX_BD_NO | MCF5272_FEC_RX_BD_OV))
lwip_stats.link.err++;
else
if (flags & MCF5272_FEC_RX_BD_CR)
lwip_stats.link.chkerr++; // CRC errors
#endif
/* Drop errored frame */
pbuf_free(p);
} else {
/* Good frame. increment stat */
#ifdef LINK_STATS
lwip_stats.link.recv++;
#endif
eth_input(p, mcf5272->netif);
}
}
INC_RX_BD_INDEX(rx_remove_eof);
}
mcf5272->rx_remove = rx_remove_sof;
/* clear interrupt status for rx interrupt */
old_level = sys_disable_interrupts();
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_EIR_RXF);
value = MCF5272_RD_FEC_IMR(imm);
/* Set rx interrupt bit again */
MCF5272_WR_FEC_IMR(imm, (value | MCF5272_FEC_IMR_RXFEN));
/* Now we can re-enable higher priority interrupts again */
sys_restore_interrupts(old_level);
/* Fill up empty descriptor rings */
fill_rx_ring(mcf5272);
/* Tell fec that we have filled up her ring */
MCF5272_WR_FEC_RDAR(imm, 1);
return;
}
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
mcf5272if_t *mcf5272;
MCF5272_IMM *imm;
VOID (*old_lisr)(INT); /* old LISR */
u32_t value;
u32_t old_level;
struct pbuf *p;
int i;
mcf5272 = netif->state;
imm = mcf5272->imm;
/* Initialize our ethernet address */
sys_get_eth_addr(mcf5272->ethaddr);
/* First disable fec */
disable_fec(mcf5272);
/* Plug appropriate low level interrupt vectors */
sys_setvect(MCF5272_VECTOR_ERx, mcf5272fec_rx, mcf5272_dis_rx_int);
sys_setvect(MCF5272_VECTOR_ETx, mcf5272fec_tx_cleanup, mcf5272_dis_tx_int);
//sys_setvect(MCF5272_VECTOR_ENTC, mcf5272fec_ntc);
/* Set the I_MASK register to enable only rx & tx frame interrupts */
MCF5272_WR_FEC_IMR(imm, MCF5272_FEC_IMR_TXFEN | MCF5272_FEC_IMR_RXFEN);
/* Clear I_EVENT register */
MCF5272_WR_FEC_EIR(imm,0xFFFFFFFF);
/* Set up the appropriate interrupt levels */
/* Disable interrupts, since this is a read/modify/write operation */
old_level = sys_disable_interrupts();
value = MCF5272_RD_SIM_ICR3(imm);
MCF5272_WR_SIM_ICR3(imm, value | MCF5272_SIM_ICR_ERX_IL(FEC_LEVEL) |
MCF5272_SIM_ICR_ETX_IL(FEC_LEVEL));
sys_restore_interrupts(old_level);
/* Set the source address for the controller */
MCF5272_WR_FEC_MALR(imm,0
| (mcf5272->ethaddr->addr[0] <<24)
| (mcf5272->ethaddr->addr[1] <<16)
| (mcf5272->ethaddr->addr[2] <<8)
| (mcf5272->ethaddr->addr[3] <<0));
MCF5272_WR_FEC_MAUR(imm,0
| (mcf5272->ethaddr->addr[4] <<24)
| (mcf5272->ethaddr->addr[5] <<16));
/* Initialize the hash table registers */
/* We are not supporting multicast addresses */
MCF5272_WR_FEC_HTUR(imm,0);
MCF5272_WR_FEC_HTLR(imm,0);
/* Set Receive Buffer Size. We subtract 16 because the start of the receive
* buffer MUST be divisible by 16, so depending on where the payload really
* starts in the pbuf, we might be increasing the start point by up to 15 bytes.
* See the alignment code in fill_rx_ring() */
/* There might be an offset to the payload address and we should subtract
* that offset */
p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
i = 0;
if (p)
{
struct pbuf *q = p;
while ((q = q->next) != 0)
i += q->len;
mcf5272->rx_buf_len = PBUF_POOL_BUFSIZE-16-i;
pbuf_free(p);
}
MCF5272_WR_FEC_EMRBR(imm, (u16_t) mcf5272->rx_buf_len);
/* Point to the start of the circular Rx buffer descriptor queue */
MCF5272_WR_FEC_ERDSR(imm, ((u32_t) &mcf5272->rxbd_a[0]));
/* Point to the start of the circular Tx buffer descriptor queue */
MCF5272_WR_FEC_ETDSR(imm, ((u32_t) &mcf5272->txbd_a[0]));
/* Set the tranceiver interface to MII mode */
MCF5272_WR_FEC_RCR(imm, 0
| MCF5272_FEC_RCR_MII_MODE);
/* | MCF5272_FEC_RCR_DRT); */ /* half duplex */
/* Only operate in half-duplex, no heart beat control */
MCF5272_WR_FEC_TCR(imm, 0);
/* Set the maximum frame length (MTU) */
MCF5272_WR_FEC_MFLR(imm, MTU_FEC);
/* Set MII bus speed */
MCF5272_WR_FEC_MSCR(imm, 0x0a);
/* Enable fec i/o pins */
value = MCF5272_RD_GPIO_PBCNT(imm);
MCF5272_WR_GPIO_PBCNT(imm, ((value & 0x0000ffff) | 0x55550000));
/* Clear MII interrupt status */
MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_IMR_MIIEN);
/* /\* Read phy ID *\/ */
/* MCF5272_WR_FEC_MMFR(imm, 0x600a0000); */
/* while (1) */
/* { */
/* value = MCF5272_RD_FEC_EIR(imm); */
/* if ((value & MCF5272_FEC_IMR_MIIEN) != 0) */
/* { */
/* MCF5272_WR_FEC_EIR(imm, MCF5272_FEC_IMR_MIIEN); */
/* break; */
/* } */
/* } */
/* phy = MCF5272_RD_FEC_MMFR(imm); */
/* Enable FEC */
enable_fec(mcf5272);
/* THIS IS FOR LEVEL ONE/INTEL PHY ONLY!!! */
/* Program Phy LED 3 to tell us transmit status */
MCF5272_WR_FEC_MMFR(imm, 0x50520412);
}
/*-----------------------------------------------------------------------------------*
* etharp timer thread
* It's only job is to initialize the timer, create a semaphore and wait on it
* forever. We need a special task to handle the arp timer.
*-----------------------------------------------------------------------------------*/
static void
etharp_timer_thread(void *arg)
{
sys_sem_t *psem = (sys_sem_t *) arg;
sys_sem_t sem;
/* Create timeout timer */
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
/* Signal previous task that it can go */
sys_sem_signal(*psem);
sem = sys_sem_new(0);
while(1)
{
sys_sem_wait(sem);
}
}
/*-----------------------------------------------------------------------------------*/
static void
etharp_timer_init(void *arg)
{
sys_thread_new((void *)etharp_timer_thread, arg);
}
/*-----------------------------------------------------------------------------------*/
/*
* mcf5272fecif_init(struct netif *netif):
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* Note that there is only one fec in a 5272!
*
*/
void
mcf5272fecif_init(struct netif *netif)
{
sys_sem_t sem;
/* Allocate our interface control block */
/* IMPORTANT NOTE: This works for 5272, but if you are using a cpu with data cache
* then you need to make sure you get this memory from non-cachable memory. */
mcf5272if = (mcf5272if_t *) calloc(1, sizeof(mcf5272if_t));
if (mcf5272if)
{
netif->state = mcf5272if;
mcf5272if->netif = netif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = mcf5272fecif_output;
netif->linkoutput = low_level_output;
netif->mtu = MTU_FEC - 18; // mtu without ethernet header and crc
mcf5272if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
mcf5272if->imm = mcf5272_get_immp();
low_level_init(netif);
etharp_init();
sem = sys_sem_new(0);
etharp_timer_init(&sem);
sys_sem_wait(sem);
sys_sem_free(sem);
}
/*
else
Give some error message if we are out of memory
*/
}
/*-----------------------------------------------------------------------------------*/

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <stdio.h>
#include "netif/tcpdump.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/inet.h"
/*-----------------------------------------------------------------------------------*/
void
tcpdump(struct pbuf *p)
{
}
/*-----------------------------------------------------------------------------------*/

38
ports/coldfire/perf.c Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "arch/perf.h"
void
perf_init(char *fname)
{
}

574
ports/coldfire/sys_arch.c Normal file
View File

@ -0,0 +1,574 @@
/* @(#)sys_arch.c
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. 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.
*
* Author: David Haas <dhaas@alum.rpi.edu>
*
*/
#include "lwip/debug.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/stats.h"
#include "nucleus.h"
#include "config.h"
#include <stdlib.h>
#include <string.h>
struct sys_thread {
struct sys_thread *next;
struct sys_timeouts timeouts;
int errno_i;
NU_TASK *pthread;
void (*function)(void *arg);
void *arg;
};
struct sys_hisr
{
struct sys_hisr *next;
NU_HISR *hisr;
void (*disablefun) (void);
u32_t vector;
};
static int num_sem = 0; // Number of semaphores created
static int num_mbox = 0; // Number of mailboxes created
static int num_thread = 0; // Number of threads created
static int num_hisr = 0; // Number of hisrs created
static sys_sem_t thread_sem; // Protect thread structure
static struct sys_thread *threads = NULL;
static struct sys_hisr *hisrs = NULL;
#define TICKS_PER_SECOND 10000
#define MS_TO_TICKS(MS) (MS * TICKS_PER_SECOND) / 1000
#define TICKS_TO_MS(TICKS) (1000 * TICKS) / TICKS_PER_SECOND
#define SYS_MBOX_SIZE 128 // Number of elements in mbox queue
#define SYS_STACK_SIZE 2048 // A minimum Nucleus stack for coldfire
#define SYS_HISR_STACK_SIZE 2048 // A minimum Nucleus stack for coldfire
/* People often make a mistake on the priority of their communications task.
The TCP/IP stack should be at a relatively low priority if it is an endpoint
(not a router) on a somewhat underpowered CPU. You are'nt going to keep up
with network traffic during a denial of service attack or misconfigured network
and you don't want an overburdened network task to cause other important tasks
(including your UI) to stop working. Drop packets! It forces flow control and
lets the rest of your system run.
*/
#define SYS_THREAD_PRIORITY 220 // Relatively low priority
/*---------------------------------------------------------------------------------*/
void
sys_init(void)
{
thread_sem = sys_sem_new(1);
return;
}
/*---------------------------------------------------------------------------------*/
static void
sys_thread_entry(UNSIGNED argc, VOID *argv)
{
/* argv is passed as a pointer to our thread structure */
struct sys_thread *p_thread = (struct sys_thread *)argv;
p_thread->function(p_thread->arg);
}
/*---------------------------------------------------------------------------------*/
static struct sys_thread *
introduce_thread(NU_TASK *id, void (*function)(void *arg), void *arg)
{
struct sys_thread *thread;
thread = (struct sys_thread *) calloc(1,sizeof(struct sys_thread));
if(thread) {
sys_arch_sem_wait(thread_sem, 0); //Wait to obtain the semaphore
thread->next = threads;
thread->timeouts.next = NULL;
thread->pthread = id;
thread->function = function;
thread->arg = arg;
threads = thread;
sys_sem_signal(thread_sem); //Release semaphore
}
return thread;
}
/*---------------------------------------------------------------------------------*/
/* We use Nucleus task as thread. Create one with a standard size stack at a standard
* priority. */
void
sys_thread_new(void (*function)(void *arg), void *arg)
{
NU_TASK *p_thread;
u8_t *p_stack;
STATUS status;
char thread_name[8] = " ";
struct sys_thread *st;
p_stack = (u8_t *) malloc(SYS_STACK_SIZE);
if (p_stack)
{
p_thread = (NU_TASK *) calloc(1,sizeof(NU_TASK));
if (p_thread)
{
/* get a new thread structure */
st = introduce_thread(p_thread, function, arg);
if (st)
{
num_thread = (num_thread +1) % 100; // Only count to 99
sprintf(thread_name, "lwip%02d", num_thread);
thread_name[strlen(thread_name)] = ' ';
status = NU_Create_Task(p_thread,
thread_name,
sys_thread_entry,
0,
st,
p_stack,
SYS_STACK_SIZE,
SYS_THREAD_PRIORITY,
0, //Disable timeslicing
NU_PREEMPT,
NU_START);
if (status == NU_SUCCESS)
return;
}
}
}
abort();
}
/*-----------------------------------------------------------------------------------*/
static struct sys_thread *
current_thread(void)
{
struct sys_thread *st;
NU_TASK *pt;
pt = NU_Current_Task_Pointer();
sys_arch_sem_wait(thread_sem, 0);
for(st = threads; st != NULL; st = st->next)
{
if(st->pthread == pt)
{
sys_sem_signal(thread_sem);
return st;
}
}
sys_sem_signal(thread_sem);
st = introduce_thread(pt, 0, 0);
if(!st) {
abort();
}
return st;
}
/*---------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
struct sys_thread *thread;
thread = current_thread();
return &thread->timeouts;
}
/*---------------------------------------------------------------------------------*/
int *
sys_arch_errno(void)
{
struct sys_thread *thread;
thread = current_thread();
return &thread->errno_i;
}
/*---------------------------------------------------------------------------------*/
sys_sem_t
sys_sem_new(u8_t count)
{
STATUS status;
NU_SEMAPHORE *sem;
char sem_name[8] = " ";
#ifdef SYS_STATS
lwip_stats.sys.sem.used++;
if(lwip_stats.sys.sem.used > lwip_stats.sys.sem.max)
{
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
}
#endif /* SYS_STATS */
/* Get memory for new semaphore */
sem = (NU_SEMAPHORE *) calloc(1,sizeof(NU_SEMAPHORE));
if (sem)
{
/* Create a unique name for semaphore based on number created */
num_sem = (num_sem + 1) % 100; // Only count to 99
sprintf(sem_name, "lwip%02d", num_sem);
sem_name[strlen(sem_name)] = ' ';
/* Ask nucleus to create semaphore */
NU_Create_Semaphore(sem,
sem_name,
count,
NU_FIFO);
}
return sem;
}
/*---------------------------------------------------------------------------------*/
void
sys_sem_free(sys_sem_t sem)
{
if (sem != SYS_SEM_NULL)
{
#ifdef SYS_STATS
lwip_stats.sys.sem.used--;
#endif /* SYS_STATS */
NU_Delete_Semaphore(sem);
free(sem);
}
}
/*---------------------------------------------------------------------------------*/
void
sys_sem_signal(sys_sem_t sem)
{
NU_Release_Semaphore(sem);
}
/*---------------------------------------------------------------------------------*/
u16_t
sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
{
UNSIGNED timestart, timespent;
STATUS status;
/* Get the current time */
timestart = NU_Retrieve_Clock();
/* Wait for the semaphore */
status = NU_Obtain_Semaphore(sem,
timeout ? MS_TO_TICKS(timeout) : NU_SUSPEND);
/* This next statement takes wraparound into account. It works. Really! */
timespent = TICKS_TO_MS(((s32_t) ((s32_t) NU_Retrieve_Clock() - (s32_t) timestart)));
if (status == NU_TIMEOUT)
return 0;
else
return timespent ? (u16_t) timespent : 1;
}
/*---------------------------------------------------------------------------------*/
sys_mbox_t
sys_mbox_new(void)
{
u32_t *p_queue_mem;
NU_QUEUE *p_queue;
char queue_name[8] = " ";
/* Allocate memory for queue */
p_queue_mem = (u32_t *) calloc(1,(SYS_MBOX_SIZE * sizeof(u32_t)));
if (p_queue_mem)
{
/* Allocate memory for queue control block */
p_queue = (NU_QUEUE *) calloc(1,sizeof(NU_QUEUE));
if (p_queue)
{
/* Create a unique name for mbox based on number created */
num_mbox = (num_mbox + 1) % 100;
sprintf(queue_name, "lwip%02d", num_mbox);
queue_name[strlen(queue_name)] = ' ';
NU_Create_Queue(p_queue,
queue_name,
p_queue_mem,
SYS_MBOX_SIZE,
NU_FIXED_SIZE,
1,
NU_FIFO);
#ifdef SYS_STATS
lwip_stats.sys.mbox.used++;
if(lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) {
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
}
#endif /* SYS_STATS */
return p_queue;
}
else
free(p_queue_mem);
}
return SYS_MBOX_NULL;
}
/*---------------------------------------------------------------------------------*/
void
sys_mbox_free(sys_mbox_t mbox)
{
VOID *p_queue_mem;
CHAR name[8];
UNSIGNED queue_size;
UNSIGNED available;
UNSIGNED messages;
OPTION message_type;
UNSIGNED message_size;
OPTION suspend_type;
UNSIGNED tasks_waiting;
NU_TASK *first_task;
STATUS status;
if (mbox != SYS_MBOX_NULL)
{
/* First we need to get address of queue memory. Ask Nucleus
for information about the queue */
status = NU_Queue_Information(mbox,
name,
&p_queue_mem,
&queue_size,
&available,
&messages,
&message_type,
&message_size,
&suspend_type,
&tasks_waiting,
&first_task);
if (status == NU_SUCCESS)
free(p_queue_mem);
NU_Delete_Queue(mbox);
free(mbox);
#ifdef SYS_STATS
lwip_stats.sys.mbox.used--;
#endif /* SYS_STATS */
}
}
/*---------------------------------------------------------------------------------
This function sends a message to a mailbox. It is unusual in that no error
return is made. This is because the caller is responsible for ensuring that
the mailbox queue will not fail. The caller does this by limiting the number
of msg structures which exist for a given mailbox.
---------------------------------------------------------------------------------*/
void
sys_mbox_post(sys_mbox_t mbox, void *msg)
{
UNSIGNED status;
DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", mbox, msg));
status = NU_Send_To_Queue(mbox,
&msg,
1,
NU_NO_SUSPEND);
ASSERT("sys_mbox_post: mbx post failed", status == NU_SUCCESS);
}
/*---------------------------------------------------------------------------------*/
u16_t
sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout)
{
UNSIGNED timestart, timespent;
STATUS status;
void *ret_msg;
UNSIGNED actual_size;
/* Get the current time */
timestart = NU_Retrieve_Clock();
/* Wait for message */
status = NU_Receive_From_Queue(mbox,
&ret_msg,
1,
&actual_size,
timeout ? MS_TO_TICKS(timeout) : NU_SUSPEND);
if (status == NU_SUCCESS)
{
if (msg)
*msg = ret_msg;
DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", mbox, ret_msg));
}
/* This next statement takes wraparound into account. It works. Really! */
timespent = TICKS_TO_MS(((s32_t) ((s32_t) NU_Retrieve_Clock() - (s32_t) timestart)));
if (status == NU_TIMEOUT)
return 0;
else
return timespent ? (u16_t) timespent : 1;
}
/*---------------------------------------------------------------------------------*/
static void
sys_arch_lisr(INT vector_number)
{
struct sys_hisr *p_hisr = hisrs;
/* Determine which HISR to activate */
while (p_hisr != NULL)
{
if (vector_number == p_hisr->vector)
{
if (p_hisr->disablefun)
(*p_hisr->disablefun)();
NU_Activate_HISR(p_hisr->hisr);
break;
}
p_hisr = p_hisr->next;
}
return;
}
/*---------------------------------------------------------------------------------*/
void
sys_setvect(u32_t vector, void (*isr_function)(void), void (*dis_funct)(void))
{
/* The passed function is called as a high level ISR on the selected vector.
It is assumed that all the functions in this module can be called by the
isr_function.
*/
struct sys_hisr *p_hisr = hisrs;
INT old_level;
NU_HISR *nucleus_hisr;
u8_t *p_stack;
STATUS status;
char hisr_name[8] = " ";
void (*old_lisr)(INT);
/* In this case a Nucleus HISR is created for the isr_function. This
* requires it's own stack. Also get memory for Nucleus HISR. */
nucleus_hisr = (NU_HISR *) calloc(1,sizeof(NU_HISR));
if (nucleus_hisr)
{
p_stack = (u8_t *) malloc(SYS_HISR_STACK_SIZE);
if (p_stack)
{
/* It is most efficient to disable interrupts for Nucleus for a short
time. Chances are we are doing this while interrupts are disabled
already during system initialization.
*/
old_level = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* It is a simplification here that once an HISR is set up for a particular
* vector it will never be set up again. This way if the init code is called
* more than once it is harmless (no memory leaks)
*/
while (p_hisr != NULL)
{
if (vector == p_hisr->vector)
{
NU_Control_Interrupts(old_level);
free(p_stack);
free(nucleus_hisr);
return;
}
p_hisr = p_hisr->next;
}
/* Get a sys_hisr structure */
p_hisr = (struct sys_hisr *) calloc(1,sizeof(struct sys_hisr));
if (p_hisr)
{
p_hisr->next = hisrs;
p_hisr->vector = vector;
p_hisr->hisr = nucleus_hisr;
p_hisr->disablefun = dis_funct;
hisrs = p_hisr;
NU_Control_Interrupts(old_level);
num_hisr = (num_hisr + 1) % 100;
sprintf(hisr_name, "lwip%02d", num_hisr);
hisr_name[strlen(hisr_name)] = ' ';
/* Ask Nucleus to create the HISR */
status = NU_Create_HISR(p_hisr->hisr,
hisr_name,
isr_function,
1, //Priority 0-2
p_stack,
SYS_HISR_STACK_SIZE);
if (status == NU_SUCCESS)
{
/* Plug vector with system lisr now */
NU_Register_LISR(vector, sys_arch_lisr, &old_lisr);
return; //Success
}
}
NU_Control_Interrupts(old_level);
}
}
/* Errors should be logged here */
abort();
}
/*---------------------------------------------------------------------------------*/
u32_t
sys_disable_interrupts(void)
{
return NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
}
/*---------------------------------------------------------------------------------*/
void
sys_restore_interrupts(u32_t old_level)
{
NU_Control_Interrupts(old_level);
}
/*********************************************************************
* void sys_get_eth_addr(struct eth_addr *eth_addr)
*
* Get configured ethernet address from nvram and return it
* in a eth_addr structure.
*********************************************************************/
void
sys_get_eth_addr(struct eth_addr *eth_addr)
{
Cfg_lan *p_lan = config_get_lan_setup();
eth_addr->addr[0] = (u8_t) ((p_lan->etheraddrhi >> 16) & 0xff);
eth_addr->addr[1] = (u8_t) ((p_lan->etheraddrhi >> 8) & 0xff);
eth_addr->addr[2] = (u8_t) ((p_lan->etheraddrhi) & 0xff);
eth_addr->addr[3] = (u8_t) ((p_lan->etheraddrlo >> 16) & 0xff);
eth_addr->addr[4] = (u8_t) ((p_lan->etheraddrlo >> 8) & 0xff);
eth_addr->addr[5] = (u8_t) ((p_lan->etheraddrlo) & 0xff);
}