Contiki 2.6

uip_arch.c

00001 /*
00002  * Copyright (c) 2007, Takahide Matsutsuka.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above
00011  *    copyright notice, this list of conditions and the following
00012  *    disclaimer in the documentation and/or other materials provided
00013  *    with the distribution.
00014  * 3. The name of the author may not be used to endorse or promote
00015  *    products derived from this software without specific prior
00016  *    written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * $Id: uip_arch.c,v 1.3 2010/10/19 18:29:04 adamdunkels Exp $
00031  *
00032  */
00033  /*
00034   * \file
00035   *     Z80 architecture-depend uip module
00036   *     for calculating checksums
00037   * \author
00038   *     Takahide Matsutsuka <markn@markn.org>
00039   */
00040 
00041 #include <stddef.h>
00042 #include "uip_arch.h"
00043 
00044 static const uint16_t sizeof_uip_ipaddr_t = sizeof(uip_ipaddr_t);
00045 static const uint16_t offset_tcpip_hdr_len = offsetof(struct uip_tcpip_hdr, len);
00046 static const uint16_t offset_tcpip_hdr_srcipaddr = offsetof(struct uip_tcpip_hdr, srcipaddr);
00047 
00048 /*--------------------------------------------------------------------------*/
00049 static void upper_layer_chksum() {
00050 __asm
00051         ;; ---------------------------------
00052         ;; static uint16_t upper_layer_chksum(uint8_t proto);
00053         ;; Stack; retl reth
00054         ;; @param C proto
00055         ;; ABCDEHL____
00056         ;; ---------------------------------
00057         ;; HL = BUF = &uip_buf[UIP_LLH_LEN]
00058         ld      hl, #_uip_buf
00059         ld      de, #UIP_LLH_LEN
00060         add     hl, de
00061         push    hl
00062         
00063         ;; HL = BUF->len[0]
00064         push    ix
00065         ld      ix, #_offset_tcpip_hdr_len
00066         ld      e, 0(ix)
00067         ld      d, 1(ix)
00068         add     hl, de
00069         pop     ix
00070         
00071         ;; DE = upper layer length
00072         ld      d, (hl)
00073         inc     hl
00074         ld      e, (hl)
00075 #if UIP_CONF_IPV6
00076 #else
00077         ld      a, e
00078         sub     a, #UIP_IPH_LEN
00079         ld      e, a
00080         jr      nc, _upper_layer_chksum_setlen2
00081         dec     d
00082 _upper_layer_chksum_setlen2:
00083 #endif
00084         ;; bc = upper_leyer_len + proto
00085         ld      b, d
00086         ld      a, e
00087         add     a, c
00088         ld      c, a
00089         jr      nc, _upper_layer_chksum_setlen3
00090         inc     b
00091 _upper_layer_chksum_setlen3:
00092         pop     hl              ; BUF
00093         push    de
00094         push    ix
00095         ld      ix, #_offset_tcpip_hdr_srcipaddr
00096         ld      e, 0(ix)
00097         ld      d, 1(ix)
00098         add     hl, de
00099         ld      e, l
00100         ld      d, h
00101         ld      ix, #_sizeof_uip_ipaddr_t
00102         ld      l, 0(ix)
00103         ld      h, 1(ix)
00104         pop     ix
00105         sla     l
00106         rl      h
00107         push    hl
00108         push    de
00109         push    bc
00110         call    _uip_arch_chksum                ; hl = sum
00111         pop     af
00112         pop     af
00113         pop     af
00114         ;; de is still stacked
00115 
00116         ld      b, h
00117         ld      c, l
00118         ld      hl, #_uip_buf
00119         ld      de, #UIP_IPH_LEN        
00120         add     hl, de
00121 _upper_layer_chksum_call:
00122         ld      de, #UIP_LLH_LEN
00123         add     hl, de
00124         push    hl
00125         push    bc
00126         call    _uip_arch_chksum
00127         pop     af
00128         pop     af
00129         pop     af
00130 
00131         ld      a, h
00132         or      a, l
00133         jr      nz, _upper_layer_uip_htons
00134         ld      hl, #0xffff
00135         jr      _upper_layer_ret
00136 _upper_layer_uip_htons:
00137         ld      a, l
00138         ld      l, h
00139         ld      h, a
00140 _upper_layer_ret:
00141 __endasm;
00142 }
00143 
00144 /*--------------------------------------------------------------------------*/
00145 uint16_t
00146 uip_ipchksum(void)
00147 {
00148 __asm
00149         ;; ---------------------------------
00150         ;; uint16_t uip_ipchksum(void);
00151         ;; Stack; retl reth
00152         ;; ABCDEHL____
00153         ;; return HL
00154         ;; ---------------------------------
00155         ld      hl, #UIP_IPH_LEN
00156         push    hl
00157         ;; HL = BUF = &uip_buf[UIP_LLH_LEN]
00158         ld      hl, #_uip_buf
00159         ;; BC = sum = 0
00160         ld      bc, #0
00161         jp      _upper_layer_chksum_call
00162 __endasm;
00163 }
00164 
00165 /*--------------------------------------------------------------------------*/
00166 #if UIP_CONF_IPV6
00167 uint16_t
00168 uip_icmp6chksum(void)
00169 {
00170 __asm
00171         ;; ---------------------------------
00172         ;; uint16_t uip_icmp6chksum(void);
00173         ;; Stack; retl reth
00174         ;; ABCDEHL____
00175         ;; return HL
00176         ;; ---------------------------------
00177         ld      c, #UIP_PROTO_ICMP6
00178         jp      _upper_layer_chksum
00179 __endasm;
00180 }
00181 #endif /* UIP_CONF_IPV6 */
00182 
00183 /*--------------------------------------------------------------------------*/
00184 uint16_t
00185 uip_tcpchksum(void)
00186 {
00187 __asm
00188         ;; ---------------------------------
00189         ;; uint16_t uip_tcpchksum(void);
00190         ;; Stack; retl reth
00191         ;; ABCDEHL____
00192         ;; return HL
00193         ;; ---------------------------------
00194         ld      c, #UIP_PROTO_TCP
00195         jp      _upper_layer_chksum
00196 __endasm;
00197 }
00198 
00199 /*--------------------------------------------------------------------------*/
00200 #if UIP_UDP_CHKSUMS
00201 uint16_t
00202 uip_udpchksum(void)
00203 {
00204 __asm
00205         ;; ---------------------------------
00206         ;; uint16_t uip_udpchksum(void);
00207         ;; Stack; retl reth
00208         ;; ABCDEHL____
00209         ;; return HL
00210         ;; ---------------------------------
00211         ld      c, #UIP_PROTO_UDP
00212         jp      _upper_layer_chksum
00213 __endasm;
00214 }
00215 #endif /* UIP_UDP_CHKSUMS */
00216 /*--------------------------------------------------------------------------*/