[haiku-commits] haiku: hrev44819 - src/system/kernel/arch/arm

  • From: ithamar.adema@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 12 Nov 2012 20:05:55 +0100 (CET)

hrev44819 adds 1 changeset to branch 'master'
old head: 75b285a9699908edbcab1c081a7c53b7d3b3ca76
new head: 4b2a1d798b16cff17633e6aedfe99b9992fa30e4

----------------------------------------------------------------------------

4b2a1d7: ARM: implement arch_cpu_user_memcpy/memset/strlcpy functions
  
  Remove the dummies from the C code and implement them in assembly,
  due to the label referencing issues with the fault handler.
  
  This code is ripe for optimisation, my ARM assembly is pretty
  basic ;)
  
  Does work though, and gets us one step closer to a full arch.

                          [ Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev44819
Commit:      4b2a1d798b16cff17633e6aedfe99b9992fa30e4
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4b2a1d7
Author:      Ithamar R. Adema <ithamar@xxxxxxxxxxxxxxxxxxx>
Date:        Mon Nov 12 19:03:48 2012 UTC

----------------------------------------------------------------------------

2 files changed, 110 insertions(+), 116 deletions(-)
src/system/kernel/arch/arm/arch_asm.S   | 110 ++++++++++++++++++++++++++
src/system/kernel/arch/arm/arch_cpu.cpp | 116 ----------------------------

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/arm/arch_asm.S 
b/src/system/kernel/arch/arm/arch_asm.S
index c51089c..eb570a5 100644
--- a/src/system/kernel/arch/arm/arch_asm.S
+++ b/src/system/kernel/arch/arm/arch_asm.S
@@ -94,6 +94,116 @@ FUNCTION(arm_get_far):
        bx      lr
 FUNCTION_END(arm_get_far)
 
+/* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, 
addr_t *faultHandler) */
+FUNCTION(arch_cpu_user_memcpy):
+       stmfd   sp!, { r4-r6 }
+       ldr     r6, [r3]
+       ldr     r4, =.L_user_memcpy_error
+       str     r4, [r3]        /* set fault handler */
+       mov     r4, r2, lsr #2  /* size / 4 */
+1:
+       ldr     r5, [r1]
+       str     r5, [r0]
+       add     r1, #4
+       add     r0, #4
+       sub     r4, #1
+       bne     1b
+2:
+       and     r4, r2, #3      /* size % 4 */
+       ldrb    r5, [r1]
+       strb    r5, [r0]
+       add     r1, #1
+       add     r0, #1
+       sub     r4, #1
+       bne     2b
+
+       str     r6, [r3]        /* restore fault handler */
+       mov     r0, #0
+       ldmfd   sp!, { r4-r6 }
+       bx      lr
+
+.L_user_memcpy_error:
+       str     r6, [r3]        /* restore fault handler */
+       mov     r0, #-1
+
+       ldmfd   sp!, { r4-r6 }
+       bx      lr
+FUNCTION_END(arch_cpu_user_memcpy)
+
+/* status_t arch_cpu_user_memset(void *to, char c, size_t count, addr_t 
*faultHandler) */
+FUNCTION(arch_cpu_user_memset):
+       stmfd   sp!, { r4-r5 }
+       ldr     r5, [r3]
+       ldr     r4, =.L_user_memset_error
+       str     r4, [r3]
+
+       and     r1, r1, #0xff
+       add     r1, r1, lsl #8
+       add     r1, r1, lsl #16
+       add     r1, r1, lsl #24
+
+       mov     r4, r2, lsr #2  /* count / 4 */
+1:
+       str     r1, [r0]
+       add     r0, r0, #4
+       sub     r4, r4, #1
+       bne     1b
+
+       and     r4, r2, #3      /* count % 4 */
+2:
+       strb    r1, [r0]
+       add     r0, r0, #1
+       sub     r4, r4, #1
+       bne     2b
+
+       mov     r0, #0
+       str     r5, [r3]
+
+       ldmfd   sp!, { r4-r5 }
+       bx      lr
+
+.L_user_memset_error:
+       mov     r0, #-1
+       str     r5, [r3]
+
+       ldmfd   sp!, { r4-r5 }
+       bx      lr
+FUNCTION_END(arch_cpu_user_memset)
+
+/* ssize_t arch_cpu_user_strlcpy(void *to, const void *from, size_t size, 
addr_t *faultHandler) */
+FUNCTION(arch_cpu_user_strlcpy):
+       stmfd   sp!, { r4-r6 }
+       ldr     r5, [r3]
+       ldr     r4, =.L_user_strlcpy_error
+       str     r4, [r3]
+       mov     r6, #0
+1:
+       ldrb    r4, [r1, r6]
+       strb    r4, [r0, r6]
+       add     r6, r6, #1
+       and     r4, #0xff       /* done yet? */
+       beq     2f
+       cmp     r6, r2          /* reached max length? */
+       blt     1b
+2:
+       mov     r4, #0
+       strb    r4, [r0, r6]
+
+       mov     r0, r4          /* return B_OK */
+       str     r5, [r3]        /* restore fault handler */
+
+       ldmfd   sp!, { r4-r6 }
+       bx      lr
+
+.L_user_strlcpy_error:
+       mov     r0, #-1
+       str     r5, [r3]
+
+       ldmfd   sp!, { r4-r6 }
+       bx      lr
+FUNCTION_END(arch_cpu_user_strlcpy)
+
+
 /*!    \fn void arch_debug_call_with_fault_handler(cpu_ent* cpu,
                jmp_buf jumpBuffer, void (*function)(void*), void* parameter)
 
diff --git a/src/system/kernel/arch/arm/arch_cpu.cpp 
b/src/system/kernel/arch/arm/arch_cpu.cpp
index 65d4795..7021427 100644
--- a/src/system/kernel/arch/arm/arch_cpu.cpp
+++ b/src/system/kernel/arch/arm/arch_cpu.cpp
@@ -159,119 +159,3 @@ arch_cpu_user_TLB_invalidate(void)
 */
 #warning WRITEME
 }
-
-
-// TODO: all functions that use fault handlers need to be implemented
-// in assembly due to problems passing in label addresses in gcc4.
-status_t
-arch_cpu_user_memcpy(void *to, const void *from, size_t size,
-       addr_t *faultHandler)
-{
-#warning WRITEME
-/*
-       char *tmp = (char *)to;
-       char *s = (char *)from;
-       addr_t oldFaultHandler = *faultHandler;
-
-       if (m68k_set_fault_handler(faultHandler, (addr_t)&&error))
-               goto error;
-
-       while (size--)
-               *tmp++ = *s++;
-
-       *faultHandler = oldFaultHandler;
-       return 0;
-
-error:
-       *faultHandler = oldFaultHandler;*/
-       return B_BAD_ADDRESS;
-}
-
-
-/**    \brief Copies at most (\a size - 1) characters from the string in \a 
from to
- *     the string in \a to, NULL-terminating the result.
- *
- *     \param to Pointer to the destination C-string.
- *     \param from Pointer to the source C-string.
- *     \param size Size in bytes of the string buffer pointed to by \a to.
- *
- *     \return strlen(\a from).
- */
-
-ssize_t
-arch_cpu_user_strlcpy(char *to, const char *from,
-       size_t size, addr_t *faultHandler)
-{
-#warning WRITEME
-/*
-       int from_length = 0;
-       addr_t oldFaultHandler = *faultHandler;
-
-       if (m68k_set_fault_handler(faultHandler, (addr_t)&&error))
-               goto error;
-
-       if (size > 0) {
-               to[--size] = '\0';
-               // copy 
-               for ( ; size; size--, from_length++, to++, from++) {
-                       if ((*to = *from) == '\0')
-                               break;
-               }
-       }
-       // count any leftover from chars
-       while (*from++ != '\0')
-               from_length++;
-
-       *faultHandler = oldFaultHandler;
-       return from_length;
-
-error:
-       *faultHandler = oldFaultHandler;*/
-       return B_BAD_ADDRESS;
-}
-
-
-status_t
-arch_cpu_user_memset(void *s, char c, size_t count, addr_t *faultHandler)
-{
-#warning WRITEME
-
-/*
-       char *xs = (char *)s;
-       addr_t oldFaultHandler = *faultHandler;
-
-       if (m68k_set_fault_handler(faultHandler, (addr_t)&&error))
-               goto error;
-
-       while (count--)
-               *xs++ = c;
-
-       *faultHandler = oldFaultHandler;
-       return 0;
-
-error:
-       *faultHandler = oldFaultHandler;*/
-
-       return B_BAD_ADDRESS;
-}
-
-
-// The purpose of this function is to trick the compiler. When setting the
-// page_handler to a label that is obviously (to the compiler) never used,
-// it may reorganize the control flow, so that the labeled part is optimized
-// away.
-// By invoking the function like this
-//
-//     if (m68k_set_fault_handler(faultHandler, (addr_t)&&error))
-//             goto error;
-//
-// the compiler has to keep the labeled code, since it can't guess the return
-// value of this (non-inlinable) function. At least in my tests it worked that
-// way, and I hope it will continue to work like this in the future.
-//
-/*bool
-m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler)
-{
-       *handlerLocation = handler;
-       return false;
-}*/


Other related posts:

  • » [haiku-commits] haiku: hrev44819 - src/system/kernel/arch/arm - ithamar . adema