1 /**
2  * \file
3  * \brief ARM virtualization interface.
4  */
5 /*
6  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
8  *     economic rights: Technische Universität Dresden (Germany)
9  *
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  *
14  * As a special exception, you may use this file as part of a free software
15  * library without restriction.  Specifically, if other files instantiate
16  * templates or use macros or inline functions from this file, or you compile
17  * this file and link it with other files to produce an executable, this
18  * file does not by itself cause the resulting executable to be covered by
19  * the GNU General Public License.  This exception does not however
20  * invalidate any other reasons why the executable file might be covered by
21  * the GNU General Public License.
22  */
23 #pragma once
24 
25 /**
26  * \defgroup l4_vm_tz_api VM API for TZ
27  * \brief Virtual Machine API for ARM TrustZone
28  * \ingroup l4_vm_api
29  */
30 
31 /**
32  * \internal
33  * \ingroup l4_vm_tz_api
34  */
35 struct l4_vm_tz_state_mode
36 {
37   l4_umword_t sp;
38   l4_umword_t lr;
39   l4_umword_t spsr;
40 };
41 
42 struct l4_vm_tz_state_irq_inject
43 {
44   l4_uint32_t group;
45   l4_uint32_t irqs[8];
46 };
47 
48 /**
49  * \brief state structure for TrustZone VMs
50  * \ingroup l4_vm_tz_api
51  */
52 struct l4_vm_tz_state
53 {
54   l4_umword_t r[13]; // r0 - r12
55 
56   l4_umword_t sp_usr;
57   l4_umword_t lr_usr;
58 
59   struct l4_vm_tz_state_mode irq;
60 
61   l4_umword_t r_fiq[5]; // r8 - r12
62   struct l4_vm_tz_state_mode fiq;
63   struct l4_vm_tz_state_mode abt;
64   struct l4_vm_tz_state_mode und;
65   struct l4_vm_tz_state_mode svc;
66 
67   l4_umword_t pc;
68   l4_umword_t cpsr;
69 
70   l4_umword_t pending_events;
71   l4_uint32_t cpacr;
72   l4_umword_t cp10_fpexc;
73 
74   l4_umword_t pfs;
75   l4_umword_t pfa;
76   l4_umword_t exit_reason;
77 
78   struct l4_vm_tz_state_irq_inject irq_inject;
79 };
80 
81 enum L4_vm_exit_reason
82 {
83   L4_vm_exit_reason_vmm_call   = 1,
84   L4_vm_exit_reason_inst_abort = 2,
85   L4_vm_exit_reason_data_abort = 3,
86   L4_vm_exit_reason_irq        = 4,
87   L4_vm_exit_reason_fiq        = 5,
88   L4_vm_exit_reason_undef      = 6,
89 };
90 
91 L4_INLINE int
92 l4_vm_tz_irq_inject(struct l4_vm_tz_state *state, unsigned irq);
93 
94 L4_INLINE int
l4_vm_tz_irq_inject(struct l4_vm_tz_state * state,unsigned irq)95 l4_vm_tz_irq_inject(struct l4_vm_tz_state *state, unsigned irq)
96 {
97   if (irq > sizeof(state->irq_inject.irqs) * 8)
98     return -L4_EINVAL;
99 
100   unsigned g = irq / 32;
101   state->irq_inject.group   |= 1 << g;
102   state->irq_inject.irqs[g] |= 1 << (irq & 31);
103 
104   return 0;
105 }
106