Contiki 2.5
uip_arch.c
1 /*
2  * Copyright (c) 2007, Takahide Matsutsuka.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $Id: uip_arch.c,v 1.3 2010/10/19 18:29:04 adamdunkels Exp $
31  *
32  */
33  /*
34  * \file
35  * Z80 architecture-depend uip module
36  * for calculating checksums
37  * \author
38  * Takahide Matsutsuka <markn@markn.org>
39  */
40 
41 #include <stddef.h>
42 #include "uip_arch.h"
43 
44 static const u16_t sizeof_uip_ipaddr_t = sizeof(uip_ipaddr_t);
45 static const u16_t offset_tcpip_hdr_len = offsetof(struct uip_tcpip_hdr, len);
46 static const u16_t offset_tcpip_hdr_srcipaddr = offsetof(struct uip_tcpip_hdr, srcipaddr);
47 
48 /*--------------------------------------------------------------------------*/
49 static void upper_layer_chksum() {
50 __asm
51  ;; ---------------------------------
52  ;; static u16_t upper_layer_chksum(u8_t proto);
53  ;; Stack; retl reth
54  ;; @param C proto
55  ;; ABCDEHL____
56  ;; ---------------------------------
57  ;; HL = BUF = &uip_buf[UIP_LLH_LEN]
58  ld hl, #_uip_buf
59  ld de, #UIP_LLH_LEN
60  add hl, de
61  push hl
62 
63  ;; HL = BUF->len[0]
64  push ix
65  ld ix, #_offset_tcpip_hdr_len
66  ld e, 0(ix)
67  ld d, 1(ix)
68  add hl, de
69  pop ix
70 
71  ;; DE = upper layer length
72  ld d, (hl)
73  inc hl
74  ld e, (hl)
75 #if UIP_CONF_IPV6
76 #else
77  ld a, e
78  sub a, #UIP_IPH_LEN
79  ld e, a
80  jr nc, _upper_layer_chksum_setlen2
81  dec d
82 _upper_layer_chksum_setlen2:
83 #endif
84  ;; bc = upper_leyer_len + proto
85  ld b, d
86  ld a, e
87  add a, c
88  ld c, a
89  jr nc, _upper_layer_chksum_setlen3
90  inc b
91 _upper_layer_chksum_setlen3:
92  pop hl ; BUF
93  push de
94  push ix
95  ld ix, #_offset_tcpip_hdr_srcipaddr
96  ld e, 0(ix)
97  ld d, 1(ix)
98  add hl, de
99  ld e, l
100  ld d, h
101  ld ix, #_sizeof_uip_ipaddr_t
102  ld l, 0(ix)
103  ld h, 1(ix)
104  pop ix
105  sla l
106  rl h
107  push hl
108  push de
109  push bc
110  call _uip_arch_chksum ; hl = sum
111  pop af
112  pop af
113  pop af
114  ;; de is still stacked
115 
116  ld b, h
117  ld c, l
118  ld hl, #_uip_buf
119  ld de, #UIP_IPH_LEN
120  add hl, de
121 _upper_layer_chksum_call:
122  ld de, #UIP_LLH_LEN
123  add hl, de
124  push hl
125  push bc
126  call _uip_arch_chksum
127  pop af
128  pop af
129  pop af
130 
131  ld a, h
132  or a, l
133  jr nz, _upper_layer_uip_htons
134  ld hl, #0xffff
135  jr _upper_layer_ret
136 _upper_layer_uip_htons:
137  ld a, l
138  ld l, h
139  ld h, a
140 _upper_layer_ret:
141 __endasm;
142 }
143 
144 /*--------------------------------------------------------------------------*/
145 u16_t
147 {
148 __asm
149  ;; ---------------------------------
150  ;; u16_t uip_ipchksum(void);
151  ;; Stack; retl reth
152  ;; ABCDEHL____
153  ;; return HL
154  ;; ---------------------------------
155  ld hl, #UIP_IPH_LEN
156  push hl
157  ;; HL = BUF = &uip_buf[UIP_LLH_LEN]
158  ld hl, #_uip_buf
159  ;; BC = sum = 0
160  ld bc, #0
161  jp _upper_layer_chksum_call
162 __endasm;
163 }
164 
165 /*--------------------------------------------------------------------------*/
166 #if UIP_CONF_IPV6
167 u16_t
168 uip_icmp6chksum(void)
169 {
170 __asm
171  ;; ---------------------------------
172  ;; u16_t uip_icmp6chksum(void);
173  ;; Stack; retl reth
174  ;; ABCDEHL____
175  ;; return HL
176  ;; ---------------------------------
177  ld c, #UIP_PROTO_ICMP6
178  jp _upper_layer_chksum
179 __endasm;
180 }
181 #endif /* UIP_CONF_IPV6 */
182 
183 /*--------------------------------------------------------------------------*/
184 u16_t
186 {
187 __asm
188  ;; ---------------------------------
189  ;; u16_t uip_tcpchksum(void);
190  ;; Stack; retl reth
191  ;; ABCDEHL____
192  ;; return HL
193  ;; ---------------------------------
194  ld c, #UIP_PROTO_TCP
195  jp _upper_layer_chksum
196 __endasm;
197 }
198 
199 /*--------------------------------------------------------------------------*/
200 #if UIP_UDP_CHKSUMS
201 u16_t
202 uip_udpchksum(void)
203 {
204 __asm
205  ;; ---------------------------------
206  ;; u16_t uip_udpchksum(void);
207  ;; Stack; retl reth
208  ;; ABCDEHL____
209  ;; return HL
210  ;; ---------------------------------
211  ld c, #UIP_PROTO_UDP
212  jp _upper_layer_chksum
213 __endasm;
214 }
215 #endif /* UIP_UDP_CHKSUMS */
216 /*--------------------------------------------------------------------------*/