Home | History | Annotate | Download | only in arm
      1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // CPU specific code for arm independent of OS goes here.
      6 #ifdef __arm__
      7 #ifdef __QNXNTO__
      8 #include <sys/mman.h>  // for cache flushing.
      9 #undef MAP_TYPE
     10 #else
     11 #include <sys/syscall.h>  // for cache flushing.
     12 #endif
     13 #endif
     14 
     15 #include "src/v8.h"
     16 
     17 #if V8_TARGET_ARCH_ARM
     18 
     19 #include "src/cpu.h"
     20 #include "src/macro-assembler.h"
     21 #include "src/simulator.h"  // for cache flushing.
     22 
     23 namespace v8 {
     24 namespace internal {
     25 
     26 void CPU::FlushICache(void* start, size_t size) {
     27   // Nothing to do flushing no instructions.
     28   if (size == 0) {
     29     return;
     30   }
     31 
     32 #if defined(USE_SIMULATOR)
     33   // Not generating ARM instructions for C-code. This means that we are
     34   // building an ARM emulator based target.  We should notify the simulator
     35   // that the Icache was flushed.
     36   // None of this code ends up in the snapshot so there are no issues
     37   // around whether or not to generate the code when building snapshots.
     38   Simulator::FlushICache(Isolate::Current()->simulator_i_cache(), start, size);
     39 #elif V8_OS_QNX
     40   msync(start, size, MS_SYNC | MS_INVALIDATE_ICACHE);
     41 #else
     42   // Ideally, we would call
     43   //   syscall(__ARM_NR_cacheflush, start,
     44   //           reinterpret_cast<intptr_t>(start) + size, 0);
     45   // however, syscall(int, ...) is not supported on all platforms, especially
     46   // not when using EABI, so we call the __ARM_NR_cacheflush syscall directly.
     47 
     48   register uint32_t beg asm("a1") = reinterpret_cast<uint32_t>(start);
     49   register uint32_t end asm("a2") =
     50       reinterpret_cast<uint32_t>(start) + size;
     51   register uint32_t flg asm("a3") = 0;
     52   #if defined (__arm__) && !defined(__thumb__)
     53     // __arm__ may be defined in thumb mode.
     54     register uint32_t scno asm("r7") = __ARM_NR_cacheflush;
     55     asm volatile(
     56         "svc 0x0"
     57         : "=r" (beg)
     58         : "0" (beg), "r" (end), "r" (flg), "r" (scno));
     59   #else
     60     // r7 is reserved by the EABI in thumb mode.
     61     asm volatile(
     62     "@   Enter ARM Mode  \n\t"
     63         "adr r3, 1f      \n\t"
     64         "bx  r3          \n\t"
     65         ".ALIGN 4        \n\t"
     66         ".ARM            \n"
     67     "1:  push {r7}       \n\t"
     68         "mov r7, %4      \n\t"
     69         "svc 0x0         \n\t"
     70         "pop {r7}        \n\t"
     71     "@   Enter THUMB Mode\n\t"
     72         "adr r3, 2f+1    \n\t"
     73         "bx  r3          \n\t"
     74         ".THUMB          \n"
     75     "2:                  \n\t"
     76         : "=r" (beg)
     77         : "0" (beg), "r" (end), "r" (flg), "r" (__ARM_NR_cacheflush)
     78         : "r3");
     79   #endif
     80 #endif
     81 }
     82 
     83 } }  // namespace v8::internal
     84 
     85 #endif  // V8_TARGET_ARCH_ARM
     86