Index: arch/v850/README =================================================================== RCS file: /var/cvs/uClinux-2.4.x/arch/v850/README,v retrieving revision 1.2 diff -u -r1.2 README --- arch/v850/README 2002/01/29 22:29:42 1.2 +++ arch/v850/README 2002/04/26 07:12:21 @@ -1,4 +1,4 @@ -This port to the NEC v850e processor supports the following platforms: +This port to the NEC V850E processor supports the following platforms: + The gdb v850e simulator (CONFIG_SIM); see the subdirectory `sim' for some more support files for this. @@ -9,6 +9,9 @@ with the Multi-debugger monitor ROM (for the Green Hills Multi debugger). The optional RTE-MOTHER-A motherboard is also supported, which allows PCI boards to be used. + + + The sim85e2c simulator, which is a verilog simulation of the V850E2 + NA85E2C cpu core. Porting to anything with a V850E/MA1 or MA2 processor should be simple. See the file and the files it includes for an example of Index: arch/v850/config.in =================================================================== RCS file: /var/cvs/uClinux-2.4.x/arch/v850/config.in,v retrieving revision 1.4 diff -u -r1.4 config.in --- arch/v850/config.in 2002/04/26 00:49:36 1.4 +++ arch/v850/config.in 2002/04/26 07:12:21 @@ -86,6 +86,10 @@ # The sim85e2c simulator uses the v850e2 architecture (superset of v850e) define_bool CONFIG_V850E2 y define_bool CONFIG_ZERO_BSS n + + # The crappy-ass zone allocator requires that the start of allocatable + # memory be aligned to the largest possible allocation. + define_int CONFIG_FORCE_MAX_ZONEORDER 8 fi if [ "$CONFIG_RTE_CB" = "y" ]; then Index: arch/v850/lib/memcpy.c =================================================================== RCS file: /var/cvs/uClinux-2.4.x/arch/v850/lib/memcpy.c,v retrieving revision 1.3 diff -u -r1.3 memcpy.c --- arch/v850/lib/memcpy.c 2002/04/26 00:49:38 1.3 +++ arch/v850/lib/memcpy.c 2002/04/26 07:12:21 @@ -14,48 +14,84 @@ #include #include -#define CHUNK_SIZE 32 /* bytes */ -#define CHUNK_MASK (CHUNK_SIZE - 1) - +#define CHUNK_SIZE 32 /* bytes */ #define CHUNK_ALIGNED(addr) (((unsigned long)addr & 0x3) == 0) + +/* Note that this macro uses 8 call-clobbered registers (not including + R1), which are few enough so that the following functions don't need + to spill anything to memory. It also uses R1, which is nominally + reserved for the assembler, but here it should be OK. */ +#define COPY_CHUNK(src, dst) \ + asm ("mov %0, ep;" \ + "sld.w 0[ep], r1; sld.w 4[ep], r12;" \ + "sld.w 8[ep], r13; sld.w 12[ep], r14;" \ + "sld.w 16[ep], r15; sld.w 20[ep], r17;" \ + "sld.w 24[ep], r18; sld.w 28[ep], r19;" \ + "mov %1, ep;" \ + "sst.w r1, 0[ep]; sst.w r12, 4[ep];" \ + "sst.w r13, 8[ep]; sst.w r14, 12[ep];" \ + "sst.w r15, 16[ep]; sst.w r17, 20[ep];" \ + "sst.w r18, 24[ep]; sst.w r19, 28[ep]" \ + :: "r" (src), "r" (dst) \ + : "r1", "r12", "r13", "r14", "r15", \ + "r17", "r18", "r19", "ep", "memory"); -inline void *memcpy (void *dst, const void *src, __kernel_size_t count) +void *memcpy (void *dst, const void *src, __kernel_size_t size) { - if (count >= CHUNK_SIZE && CHUNK_ALIGNED (src) && CHUNK_ALIGNED (dst)){ + char *_dst = dst; + const char *_src = src; + + if (size >= CHUNK_SIZE && CHUNK_ALIGNED(_src) && CHUNK_ALIGNED(_dst)) { /* Copy large blocks efficiently. */ - unsigned num_chunks = count / CHUNK_SIZE; - for (; num_chunks; num_chunks--) { - asm ("mov %0, ep;" - "sld.w 0[ep], r11; sld.w 4[ep], r12;" - "sld.w 8[ep], r13; sld.w 12[ep], r14;" - "sld.w 16[ep], r15; sld.w 20[ep], r17;" - "sld.w 24[ep], r18; sld.w 28[ep], r19;" - "mov %1, ep;" - "sst.w r11, 0[ep]; sst.w r12, 4[ep];" - "sst.w r13, 8[ep]; sst.w r14, 12[ep];" - "sst.w r15, 16[ep]; sst.w r17, 20[ep];" - "sst.w r18, 24[ep]; sst.w r19, 28[ep]" - :: "r" (src), "r" (dst) - : "r11", "r12", "r13", "r14", "r15", - "r17", "r18", "r19", "ep", "memory"); - src += CHUNK_SIZE; - dst += CHUNK_SIZE; + unsigned count; + for (count = size / CHUNK_SIZE; count; count--) { + COPY_CHUNK (_src, _dst); + _src += CHUNK_SIZE; + _dst += CHUNK_SIZE; } - count %= CHUNK_SIZE; + size %= CHUNK_SIZE; } - if (count > 0) { - char *_dst = dst; - const char *_src = src; + if (size > 0) do *_dst++ = *_src++; - while (--count); - } + while (--size); return dst; } + +void bcopy (const char *src, char *dst, int size) +{ + memcpy (dst, src, size); +} -void bcopy (const char *src, char *dst, int count) +void *memmove (void *dst, const void *src, __kernel_size_t size) { - memcpy (dst, src, count); + if ((unsigned long)dst < (unsigned long)src + || (unsigned long)src + size < (unsigned long)dst) + return memcpy (dst, src, size); + else { + char *_dst = dst + size; + const char *_src = src + size; + + if (size >= CHUNK_SIZE + && CHUNK_ALIGNED (_src) && CHUNK_ALIGNED (_dst)) + { + /* Copy large blocks efficiently. */ + unsigned count; + for (count = size / CHUNK_SIZE; count; count--) { + _src -= CHUNK_SIZE; + _dst -= CHUNK_SIZE; + COPY_CHUNK (_src, _dst); + } + size %= CHUNK_SIZE; + } + + if (size > 0) + do + *--_dst = *--_src; + while (--size); + + return _dst; + } } Index: include/asm-v850/string.h =================================================================== RCS file: /var/cvs/uClinux-2.4.x/include/asm-v850/string.h,v retrieving revision 1.3 diff -u -r1.3 string.h --- include/asm-v850/string.h 2002/04/26 00:49:39 1.3 +++ include/asm-v850/string.h 2002/04/26 07:12:30 @@ -17,9 +17,11 @@ #define __HAVE_ARCH_BCOPY #define __HAVE_ARCH_MEMCPY #define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMMOVE extern void *memcpy (void *, const void *, __kernel_size_t); extern void bcopy (const char *, char *, int); extern void *memset (void *, int, __kernel_size_t); +extern void *memmove (void *, const void *, __kernel_size_t); #endif /* __V850_STRING_H__ */