Add assembler checksum calculation support for z80 port.

This commit is contained in:
matsutsuka 2007-09-01 11:14:50 +00:00
parent af9bf1810c
commit 4766593ff7
4 changed files with 420 additions and 57 deletions

View file

@ -2,7 +2,7 @@
# Makefile for z80/SDCC
# @author Takahide Matsutsuka <markn@markn.org>
#
# $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

View file

@ -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 <markn@markn.org>
* Takahide Matsutsuka <markn@markn.org>
*/
#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__ */

View file

@ -9,14 +9,21 @@
;;; \author
;;; Takahide Matsutsuka <markn@markn.org>
;;;
.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::

216
cpu/z80/uip_arch.c Normal file
View file

@ -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 <markn@markn.org>
*/
#include <stddef.h>
#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 */
/*--------------------------------------------------------------------------*/