diff --git a/cpu/z80/Makefile.z80 b/cpu/z80/Makefile.z80 index b223c2c2a..1255a9ef6 100644 --- a/cpu/z80/Makefile.z80 +++ b/cpu/z80/Makefile.z80 @@ -2,7 +2,7 @@ # Makefile for z80/SDCC # @author Takahide Matsutsuka # -# $Id: Makefile.z80,v 1.1 2007/08/30 14:39:16 matsutsuka Exp $ +# $Id: Makefile.z80,v 1.2 2007/09/01 11:14:52 matsutsuka Exp $ # ### Compiler definitions @@ -19,11 +19,11 @@ CFLAGS += -I. -I$(CONTIKI) -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ ${addprefix -I,$(APPDIRS)} $(APP_INCLUDES) \ --std-c99 --vc -mz80 -ASFLAGS += +ASFLAGS += -l LDFLAGS += -mz80 AROPTS = -a -CONTIKI_SOURCEFILES += strcasecmp.c mtarch.c +CONTIKI_SOURCEFILES += strcasecmp.c mtarch.c uip_arch.c CONTIKI_ASMFILES += uip_arch-asm.S contiki-$(TARGET).o: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) $(CONTIKI_ASMOBJECTFILES) @@ -32,4 +32,8 @@ contiki-$(TARGET).o: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) $(CONTIKI_ASM contiki.ihex: contiki-$(TARGET).o $(LD) $(LDFLAGS) -DAUTOSTART_ENABLE $(CONTIKI_TARGET_MAIN) -lcontiki-$(TARGET).o -o $@ +CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 +$(OBJECTDIR)/%.o: %.S + $(AS) $(ASFLAGS) -o $@ $< + #CONTIKI_TARGET_DIRS += $(CONTIKI_CPU)/net diff --git a/cpu/z80/contiki-sdcc-conf.h b/cpu/z80/contiki-sdcc-conf.h index 28637df4f..6678aa86e 100644 --- a/cpu/z80/contiki-sdcc-conf.h +++ b/cpu/z80/contiki-sdcc-conf.h @@ -27,16 +27,16 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: contiki-sdcc-conf.h,v 1.1 2007/08/30 14:39:16 matsutsuka Exp $ + * $Id: contiki-sdcc-conf.h,v 1.2 2007/09/01 11:14:52 matsutsuka Exp $ * */ /* * \file - * This file contains a set of configuration for using SDCC as a compiler. + * This file contains a set of configuration for using SDCC as a compiler. * * \author - * Takahide Matsutsuka + * Takahide Matsutsuka */ #ifndef __CONTIKI_SDCC_CONF_H__ @@ -64,15 +64,22 @@ typedef unsigned int size_t; #define CCIF #define CLIF -/* uIP configurations */ -/* uip_add32 */ +/* + * Enable architecture-depend checksum calculation + * for uIP configuration. + * @see uip_arch.h + * @see uip_arch-asm.S + */ #define UIP_ARCH_ADD32 1 +#define UIP_ARCH_CHKSUM 1 +#define UIP_ARCH_IPCHKSUM -#define uip_ipaddr_copy(dest, src) \ - memcpy(dest, src, sizeof(*dest)) #define CC_CONF_ASSIGN_AGGREGATE(dest, src) \ memcpy(dest, src, sizeof(*dest)) #define CC_CONF_INC_CAST_POINTER(type, data) \ - data = ((type) data) + 1 + data = ((type)data) + 1 + +#define uip_ipaddr_copy(dest, src) \ + memcpy(dest, src, sizeof(*dest)) #endif /* __CONTIKI_SDCC_CONF_H__ */ diff --git a/cpu/z80/uip_arch-asm.S b/cpu/z80/uip_arch-asm.S index b31fbf7cd..0f9decbc1 100644 --- a/cpu/z80/uip_arch-asm.S +++ b/cpu/z80/uip_arch-asm.S @@ -9,14 +9,21 @@ ;;; \author ;;; Takahide Matsutsuka ;;; - + .module uip_arch-asm + + ;; export symbols .globl _uip_add32 - .globl _uip_acc32 + .globl _uip_arch_chksum + .globl _uip_chksum - .area _GSINIT + ;; import symbols + .globl _uip_acc32 + .globl _uip_buf - .area _DATA + .area _DATA + .area _GSINIT + .area _CODE ;; --------------------------------- @@ -28,58 +35,187 @@ ;; --------------------------------- _uip_add32_start:: _uip_add32: - ld hl,#2 - add hl,sp - ;; HL indicates #_op32l - ld e,(hl) + ;; HL = #_op32l + ld hl, #2 + add hl, sp + + ;; DE = #(_op32) + ld e, (hl) inc hl - ld d,(hl) + ld d, (hl) inc hl - ld c,(hl) + + ;; BC = op16 + ld c, (hl) inc hl - ld b,(hl) - ;; BC indicates op16 - ld l,e - ld h,d - ;; HL indicates #_op32 - ld de,#_uip_acc32 - ;; DE indicates #_uip_acc32 - ;; uip_acc32[0] = op32[0] + op16l; - ld a,(hl) - add a,c - ld (de),a - inc hl - inc de - ;; uip_acc32[1] = op32[1] + op16h + carry; - ld a,(hl) - adc a,b - ld (de),a - inc hl - inc de - jr nc,_uip_add32_exit - ld a,(hl) + ld b, (hl) + + ;; HL = #(_op32) + 3 + ld hl, #3 + add hl, de + + ;; DE = #_uip_acc32 + 3 + ld de, #_uip_acc32 + 3 + + ;; uip_acc32[3] = op32[3] + op16l; + ld a, (hl) + add a, c + ld (de), a + + ;; uip_acc32[2] = op32[2] + op16h + carry; + dec hl + dec de + ld a, (hl) + adc a, b + ld (de), a + jr nc, _uip_add32_nocarry1 + + ;; uip_acc32[1] + dec hl + dec de + ld a, (hl) inc a - ld (de),a - inc hl - inc de - jr nc,_uip_add32_exit - ld a,(hl) + ld (de), a + jr nz, _uip_add32_nocarry0 + + ;; uip_acc32[0] + dec hl + dec de + ld a, (hl) inc a - ld (de),a + ld (de), a ret -_uip_add32_exit: - ld a,(hl) - ld (de),a - inc hl - inc de - ld a,(hl) - ld (de),a +_uip_add32_nocarry1: + ;; uip_acc32[1] + dec hl + dec de + ld a, (hl) + ld (de), a + +_uip_add32_nocarry0: + ;; uip_acc32[0] + dec hl + dec de + ld a, (hl) + ld (de), a ret _uip_add32_end:: + ;; --------------------------------- - ;; u16_t uip_chksum(void); + ;; static u16_t chksum(u16_t sum, const u8_t *data, u16_t len) ;; Stack; retl reth suml sumh datal datah lenl lenh ;; ABCDEHL____ ;; return HL - ;; _uip_acc32 = op32 + op16 ;; --------------------------------- +_uip_arch_chksum_start:: +_uip_arch_chksum: + push ix + ;; IX = #_suml + ld ix, #4 + add ix, sp + ;; BC = sum + ld c, 0(ix) + ld b, 1(ix) + ;; DE = #data + ld e, 2(ix) + ld d, 3(ix) + + ;; (lenl, lenh) <- dataptr + len - 1 (last address) + ;; (len) + DE - 1 -> (len) + ld l, 4(ix) + ld h, 5(ix) + add hl, de + dec hl + ld 4(ix), l + ld 5(ix), h + +_uip_arch_chksum_loop: + ;; compare HL(last address) and DE(dataptr) + ;; HL - DE + ;; if (HL < DE) C,NZ else if (HL = DE) NC,Z=1 otherwise NC,NZ + ;; HL = last address, DE = current pointer + ld l, 4(ix) + ld h, 5(ix) + + ld a, h + sub d + jr nz, _uip_arch_chksum_compared + ld a, l + sub e + ;; if (last address == dataptr) _uip_arch_chksum_loop_exit_add_trailing + jr z, _uip_arch_chksum_loop_exit_add_trailing +_uip_arch_chksum_compared: + ;; if (last address > dataptr) _uip_arch_chksum_loop_exit + jr c, _uip_arch_chksum_loop_exit + ;; bc = dataptr[0],dataptr[1] + bc + ld a, (de) + ld h, a + inc de + ld a, (de) + ld l, a + push hl + add hl, bc + inc de + ld b, h + ld c, l + ;; HL = t + pop hl + ;; BC - HL + ;; if (sumBC < tHL) sum++ + ld a, b + sub h + jr nz, _uip_arch_chksum_compared_t + ld a, c + sub l +_uip_arch_chksum_compared_t: + jr nc, _uip_arch_chksum_nocarry_t + inc bc +_uip_arch_chksum_nocarry_t: + jr _uip_arch_chksum_loop +_uip_arch_chksum_loop_exit_add_trailing: + ;; HL = last address + ;; bc = bc + (last address)<<8 + ld a, b + add a, (hl) + ld b, a + jr nc, _uip_arch_chksum_loop_exit + inc bc +_uip_arch_chksum_loop_exit: + ld l, c + ld h, b + pop ix + ret +_uip_arch_chksum_end:: + + ;; --------------------------------- + ;; u16_t uip_chksum(void); + ;; Stack; retl reth datal datah lenl lenh + ;; ABCDEHL____ + ;; return HL + ;; return htons(chksum(0, (u8_t *)data, len)); + ;; --------------------------------- +_uip_chksum_start:: +_uip_chksum: + ld hl, #5 + add hl, sp + ;; HL indicates #_lenh + ld b, #2 +_uip_chksum_loop: + ld d, (hl) + dec hl + ld e, (hl) + dec hl + push de + djnz _uip_chksum_loop + ld bc, #0 + push bc + call _uip_arch_chksum + pop af + pop af + pop af + ;; convert to BIG ENDIAN (htons) + ld a, l + ld l, h + ld h, a + ret +_uip_chksum_end:: diff --git a/cpu/z80/uip_arch.c b/cpu/z80/uip_arch.c new file mode 100644 index 000000000..63d40ce56 --- /dev/null +++ b/cpu/z80/uip_arch.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2007, Takahide Matsutsuka. + * 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. + * + * $Id: uip_arch.c,v 1.1 2007/09/01 11:14:52 matsutsuka Exp $ + * + */ + /* + * \file + * Z80 architecture-depend uip module + * for calculating checksums + * \author + * Takahide Matsutsuka + */ + +#include +#include "uip_arch.h" + +const u16_t SIZEOF_UIP_IPADDR_T = sizeof(uip_ipaddr_t); +const u16_t OFFSET_TCPIP_HDR_LEN = offsetof(struct uip_tcpip_hdr, len); +const u16_t OFFSET_TCPIP_HDR_SRCIPADDR = offsetof(struct uip_tcpip_hdr, srcipaddr); + +/*--------------------------------------------------------------------------*/ +static void upper_layer_chksum() { +__asm + ;; --------------------------------- + ;; static u16_t upper_layer_chksum(u8_t proto); + ;; Stack; retl reth + ;; @param C proto + ;; ABCDEHL____ + ;; --------------------------------- + ;; HL = BUF = &uip_buf[UIP_LLH_LEN] + ld hl, #_uip_buf + ld de, #UIP_LLH_LEN + add hl, de + push hl + + ;; HL = BUF->len[0] + push ix + ld ix, #_OFFSET_TCPIP_HDR_LEN + ld e, 0(ix) + ld d, 1(ix) + add hl, de + pop ix + + ;; DE = upper layer length + ld d, (hl) + inc hl + ld e, (hl) +#if UIP_CONF_IPV6 +#else + ld a, e + sub a, #UIP_IPH_LEN + ld e, a + jr nc, _upper_layer_chksum_setlen2 + dec d +_upper_layer_chksum_setlen2: +#endif + ;; bc = upper_leyer_len + proto + ld b, d + ld a, e + add a, c + ld c, a + jr nc, _upper_layer_chksum_setlen3 + inc b +_upper_layer_chksum_setlen3: + pop hl ; BUF + push de + push ix + ld ix, #_OFFSET_TCPIP_HDR_SRCIPADDR + ld e, 0(ix) + ld d, 1(ix) + add hl, de + ld e, l + ld d, h + ld ix, #_SIZEOF_UIP_IPADDR_T + ld l, 0(ix) + ld h, 1(ix) + pop ix + sla l + rl h + push hl + push de + push bc + call _uip_arch_chksum ; hl = sum + pop af + pop af + pop af + ;; de is still stacked + + ld b, h + ld c, l + ld hl, #_uip_buf + ld de, #UIP_IPH_LEN + add hl, de +_upper_layer_chksum_call: + ld de, #UIP_LLH_LEN + add hl, de + push hl + push bc + call _uip_arch_chksum + pop af + pop af + pop af + + ld a, h + or a, l + jr nz, _upper_layer_htons + ld hl, #0xffff + jr _upper_layer_ret +_upper_layer_htons: + ld a, l + ld l, h + ld h, a +_upper_layer_ret: +__endasm; +} + +/*--------------------------------------------------------------------------*/ +u16_t +uip_ipchksum(void) +{ +__asm + ;; --------------------------------- + ;; u16_t uip_ipchksum(void); + ;; Stack; retl reth + ;; ABCDEHL____ + ;; return HL + ;; --------------------------------- + ld hl, #UIP_IPH_LEN + push hl + ;; HL = BUF = &uip_buf[UIP_LLH_LEN] + ld hl, #_uip_buf + ;; BC = sum = 0 + ld bc, #0 + jp _upper_layer_chksum_call +__endasm; +} + +/*--------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +u16_t +uip_icmp6chksum(void) +{ +__asm + ;; --------------------------------- + ;; u16_t uip_icmp6chksum(void); + ;; Stack; retl reth + ;; ABCDEHL____ + ;; return HL + ;; --------------------------------- + ld c, #UIP_PROTO_ICMP6 + jp _upper_layer_chksum +__endasm; +} +#endif /* UIP_CONF_IPV6 */ + +/*--------------------------------------------------------------------------*/ +u16_t +uip_tcpchksum(void) +{ +__asm + ;; --------------------------------- + ;; u16_t uip_tcpchksum(void); + ;; Stack; retl reth + ;; ABCDEHL____ + ;; return HL + ;; --------------------------------- + ld c, #UIP_PROTO_TCP + jp _upper_layer_chksum +__endasm; +} + +/*--------------------------------------------------------------------------*/ +#if UIP_UDP_CHKSUMS +u16_t +uip_udpchksum(void) +{ +__asm + ;; --------------------------------- + ;; u16_t uip_udpchksum(void); + ;; Stack; retl reth + ;; ABCDEHL____ + ;; return HL + ;; --------------------------------- + ld c, #UIP_PROTO_UDP + jp _upper_layer_chksum +__endasm; +} +#endif /* UIP_UDP_CHKSUMS */ +/*--------------------------------------------------------------------------*/