summaryrefslogtreecommitdiff
path: root/hurd/thread.h
blob: 709e9ec9edf54994aa011b6c43e8f162d2b069ec (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
/* thread.h - Thread definitions.
   Copyright (C) 2007 Free Software Foundation, Inc.
   Written by Neal H. Walfield <neal@gnu.org>.

   This file is part of the GNU Hurd.

   The GNU Hurd is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU Hurd 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _HURD_THREAD_H
#define _HURD_THREAD_H 1

#include <hurd/types.h>
#include <hurd/startup.h>
#include <hurd/addr-trans.h>
#include <l4/syscall.h>
#include <l4/ipc.h>

enum
  {
    RM_thread_exregs = 600,
  };

struct exception_page
{
  union
  {
    /* Whether the thread is in activation mode or not.  If so, no
       exception will be delivered.

       **** ia32-exception-entry.S silently depends on the layout of
       this structure ****  */
    struct
    {
      /* Whether the thread is in activated mode.  */
      l4_word_t activated_mode : 1;
      /* Set by the kernel to indicated that there is a pending
	 message.  */
      l4_word_t pending_message : 1;
      /* Set by the kernel to indicate whether the thread was
	 interrupted while the EIP is in the transition range.  */
      l4_word_t interrupt_in_transition : 1;

      /* The value of the IP and SP when the thread was running.  */
      l4_word_t saved_ip;
      l4_word_t saved_sp;
      /* The state of the thread (as returned by _L4_exchange_regs)  */
      l4_word_t saved_thread_state;

      l4_word_t exception_handler_sp;
      l4_word_t exception_handler_ip;
      l4_word_t exception_handler_end;

      /* The exception.  */
      l4_msg_t exception;
    };
    char data[PAGESIZE];
  };
};

enum
  {
    /* Root of the address space.  */
    THREAD_ASPACE_SLOT = 0,
    /* The activity the thread is bound to.  */
    THREAD_ACTIVITY_SLOT = 1,
    /* Where exceptions are saved.  Must be a cap_page.  */
    THREAD_EXCEPTION_PAGE_SLOT = 1,
  };

enum
{
  HURD_EXREGS_SET_EXCEPTION_PAGE = 0x1000,

  HURD_EXREGS_SET_ASPACE = 0x800,
  HURD_EXREGS_SET_ACTIVITY = 0x400,
  HURD_EXREGS_SET_SP = _L4_XCHG_REGS_SET_SP,
  HURD_EXREGS_SET_IP = _L4_XCHG_REGS_SET_IP,
  HURD_EXREGS_SET_SP_IP = _L4_XCHG_REGS_SET_SP | _L4_XCHG_REGS_SET_IP,
  HURD_EXREGS_SET_EFLAGS = _L4_XCHG_REGS_SET_FLAGS,
  HURD_EXREGS_SET_USER_HANDLE = _L4_XCHG_REGS_SET_USER_HANDLE,
  HURD_EXREGS_SET_REGS = (HURD_EXREGS_SET_EXCEPTION_PAGE
			  | HURD_EXREGS_SET_ASPACE
			  | HURD_EXREGS_SET_ACTIVITY
			  | HURD_EXREGS_SET_SP
			  | HURD_EXREGS_SET_IP
			  | HURD_EXREGS_SET_EFLAGS
			  | HURD_EXREGS_SET_USER_HANDLE),

  HURD_EXREGS_GET_REGS = _L4_XCHG_REGS_DELIVER,

  HURD_EXREGS_START = _L4_XCHG_REGS_SET_HALT,
  HURD_EXREGS_STOP = _L4_XCHG_REGS_SET_HALT | _L4_XCHG_REGS_HALT,

  HURD_EXREGS_ABORT_SEND = _L4_XCHG_REGS_CANCEL_SEND,
  HURD_EXREGS_ABORT_RECEIVE = _L4_XCHG_REGS_CANCEL_RECV,
  HURD_EXREGS_ABORT_IPC = HURD_EXREGS_ABORT_SEND | _L4_XCHG_REGS_CANCEL_RECV,
};

typedef void (*hurd_exception_handler_t) (struct exception_page *);

#define RPC_STUB_PREFIX rm
#define RPC_ID_PREFIX RM
#undef RPC_TARGET_NEED_ARG
#define RPC_TARGET \
  ({ \
    extern struct hurd_startup_data *__hurd_startup_data; \
    __hurd_startup_data->rm; \
  })

#include <hurd/rpc.h>

struct hurd_thread_exregs_in
{
  l4_word_t control;

  addr_t aspace;
  l4_word_t aspace_addr_trans_flags;
  struct cap_addr_trans aspace_addr_trans;

  addr_t activity;

  addr_t exception_page;

  l4_word_t sp;
  l4_word_t ip;
  l4_word_t eflags;
  l4_word_t user_handle;

  addr_t aspace_out;
  addr_t activity_out;
  addr_t exception_page_out;
};

struct hurd_thread_exregs_out
{
  l4_word_t sp;
  l4_word_t ip;
  l4_word_t eflags;
  l4_word_t user_handle;
};

/* l4_exregs wrapper.  */
RPC (thread_exregs, 4, 1,
     addr_t, principal,
     addr_t, thread,
     l4_word_t, control,
     struct hurd_thread_exregs_in, in,
     struct hurd_thread_exregs_out *, out)

#undef RPC_STUB_PREFIX
#undef RPC_ID_PREFIX
#undef RPC_TARGET

static inline error_t
thread_stop (addr_t thread)
{
  struct hurd_thread_exregs_in in;
  struct hurd_thread_exregs_out out;

  return rm_thread_exregs (ADDR_VOID, thread,
			   HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC,
			   in, &out);
}

#endif