aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mvp/mvpkm/arm_inline.h
blob: 3689a7f9faa92c927928b2a5ceabd85b1cf0f652 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
 *
 * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; see the file COPYING.  If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#line 5

/**
 * @file
 *
 * @brief Inline stubs for ARM assembler instructions.
 */

#ifndef _ARM_INLINE_H_
#define _ARM_INLINE_H_

#define INCLUDE_ALLOW_MVPD
#define INCLUDE_ALLOW_VMX
#define INCLUDE_ALLOW_MODULE
#define INCLUDE_ALLOW_MONITOR
#define INCLUDE_ALLOW_PV
#define INCLUDE_ALLOW_GPL
#include "include_check.h"

#include "arm_types.h"
#include "arm_defs.h"

/*
 * Compiler specific include - we get the actual inline assembler macros here.
 */
#include "arm_gcc_inline.h"

/*
 * Some non-compiler specific helper functions for inline assembler macros
 * included above.
 */

/**
 * @brief Predicate giving whether interrupts are currently enabled
 *
 * @return TRUE if enabled, FALSE otherwise
 */
static inline _Bool
ARM_InterruptsEnabled(void)
{
   return !(ARM_ReadCPSR() & ARM_PSR_I);
}

/**
 * @brief Read current TTBR0 base machine address
 *
 * @return machine address given by translation table base register 0
 */
static inline MA
ARM_ReadTTBase0(void)
{
   MA ttbase;

   ARM_MRC_CP15(TTBASE0_POINTER, ttbase);

   return ttbase & ARM_CP15_TTBASE_MASK;
}

/**
 * @brief Read VFP/Adv.SIMD Extension System Register
 *
 * @param specReg which VFP/Adv. SIMD Extension System Register
 *
 * @return Read value
 */
static inline uint32
ARM_ReadVFPSystemRegister(uint8 specReg)
{
   uint32 value = 0;

   /*
    * VMRS is the instruction used to read VFP System Registers.
    * VMRS is the new UAL-syntax equivalent for the FMRX instruction.
    * At the end of the day, all these are just synonyms for MRC
    * instructions on CP10, as the VFP system registers sit in CP10
    * and MRC is the Co-processor register read instruction.
    * We use the primitive MRC synonym for VMRS here as VMRS/FMRX
    * don't seem to be working when used inside asm volatile blocks,
    * as, for some reason, the inline assembler seems to be setting
    * the VFP mode to soft-float. Moreover, we WANT the monitor code
    * to be compiled with soft-float so that the compiler doesn't use
    * VFP instructions for the monitor's own use, such as for 64-bit
    * integer operations, etc., since we pass-through the use of the
    * underlying hardware's VFP/SIMD state to the guest.
    */

   switch (specReg) {
      case ARM_VFP_SYSTEM_REG_FPSID:
         ARM_MRC_CP10(VFP_FPSID, value);
         break;
      case ARM_VFP_SYSTEM_REG_MVFR0:
         ARM_MRC_CP10(VFP_MVFR0, value);
         break;
      case ARM_VFP_SYSTEM_REG_MVFR1:
         ARM_MRC_CP10(VFP_MVFR1, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPEXC:
         ARM_MRC_CP10(VFP_FPEXC, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPSCR:
         ARM_MRC_CP10(VFP_FPSCR, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPINST:
         ARM_MRC_CP10(VFP_FPINST, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPINST2:
         ARM_MRC_CP10(VFP_FPINST2, value);
         break;
      default:
         NOT_IMPLEMENTED_JIRA(1849);
         break;
   }

   return value;
}

/**
 * @brief Write to VFP/Adv.SIMD Extension System Register
 *
 * @param specReg which VFP/Adv. SIMD Extension System Register
 * @param value desired value to be written to the System Register
 */
static inline void
ARM_WriteVFPSystemRegister(uint8 specReg, uint32 value)
{
   /*
    * VMSR is the instruction used to write to VFP System Registers.
    * VMSR is the new UAL-syntax equivalent for the FMXR instruction.
    * At the end of the day, all these are just synonyms for MCR
    * instructions on CP10, as the VFP system registers sit in CP10
    * and MCR is the Co-processor register write instruction.
    * We use the primitive MCR synonym for VMSR here as VMSR/FMXR
    * don't seem to be working when used inside asm volatile blocks,
    * as, for some reason, the inline assembler seems to be setting
    * the VFP mode to soft-float. Moreover, we WANT the monitor code
    * to be compiled with soft-float so that the compiler doesn't use
    * VFP instructions for the monitor's own use, such as for 64-bit
    * integer operations, etc., since we pass-through the use of the
    * underlying hardware's VFP/SIMD state to the guest.
    */

   switch (specReg) {
      case ARM_VFP_SYSTEM_REG_FPEXC:
         ARM_MCR_CP10(VFP_FPEXC, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPSCR:
         ARM_MCR_CP10(VFP_FPSCR, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPINST:
         ARM_MCR_CP10(VFP_FPINST, value);
         break;
      case ARM_VFP_SYSTEM_REG_FPINST2:
         ARM_MCR_CP10(VFP_FPINST2, value);
         break;
      default:
         NOT_IMPLEMENTED_JIRA(1849);
         break;
   }
}

#endif /// ifndef _ARM_INLINE_H_