summaryrefslogtreecommitdiff
path: root/viengoos/sigma0.c
blob: 2a1973d5d639188b5b98463ff4857382a80b7404 (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
/* Client code for sigma0.
   Copyright (C) 2003 Free Software Foundation, Inc.
   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.  */

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <l4.h>

#include <hurd/stddef.h>

/* The thread ID of sigma0.  */
#define SIGMA0_TID	(l4_global_id (l4_thread_user_base (), 1))

/* The message label for the sigma0 request page operation.  This is
   -6 in the upper 24 bits.  */
#define SIGMA0_RPC	(0xffa0)

/* The message label for undocumented sigma0 operations.  This is
 -1001 in the upper 24 bits.  */
#define SIGMA0_EXT	(0xc170)

/* For undocumented operations, this is the meaning of the first
   untyped word in the message (MR1).  */
#define SIGMA0_EXT_SET_VERBOSITY	1
#define SIGMA0_EXT_DUMP_MEMORY		2

/* Set the verbosity level in sigma0.  The only levels used currently
   are 1 to 3.  Returns 0 on success, otherwise an IPC error code.  */
void
sigma0_set_verbosity (l4_word_t level)
{
  l4_msg_t msg;
  l4_msg_tag_t tag;

  l4_msg_clear (msg);
  l4_set_msg_label (msg, SIGMA0_EXT);
  l4_msg_append_word (msg, SIGMA0_EXT_SET_VERBOSITY);
  l4_msg_append_word (msg, level);
  l4_msg_load (msg);
  tag = l4_send (SIGMA0_TID);
  if (l4_ipc_failed (tag))
    panic ("%s: request failed during %s: %u", __func__,
	   l4_error_code () & 1 ? "receive" : "send",
	   (l4_error_code () >> 1) & 0x7);
}


/* Request a memory dump from sigma0.  If WAIT is true, wait until the
   dump is completed before continuing.  */
void
sigma0_dump_memory (int wait)
{
  l4_msg_t msg;
  l4_msg_tag_t tag;

  l4_msg_clear (msg);
  l4_set_msg_label (msg, SIGMA0_EXT);
  l4_msg_append_word (msg, SIGMA0_EXT_DUMP_MEMORY);
  l4_msg_append_word (msg, wait);
  l4_msg_load (msg);
  if (wait)
    tag = l4_call (SIGMA0_TID);
  else
    tag = l4_send (SIGMA0_TID);
  if (l4_ipc_failed (tag))
    panic ("%s: request failed during %s: %u", __func__,
	   l4_error_code () & 1 ? "receive" : "send",
	   (l4_error_code () >> 1) & 0x7);
}


/* Request the fpage FPAGE from sigma0.  */
void
sigma0_get_fpage (l4_fpage_t fpage)
{
  l4_msg_t msg;
  l4_msg_tag_t tag;
  l4_map_item_t map_item;

  l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE));
  l4_msg_clear (msg);
  l4_set_msg_label (msg, SIGMA0_RPC);
  l4_msg_append_word (msg, fpage);
  l4_msg_append_word (msg, L4_DEFAULT_MEMORY);
  l4_msg_load (msg);
  tag = l4_call (SIGMA0_TID);
  if (l4_ipc_failed (tag))
    panic ("%s: request failed during %s: %u", __func__,
	   l4_error_code () & 1 ? "receive" : "send",
	   (l4_error_code () >> 1) & 0x7);
  if (l4_untyped_words (tag) != 0 || l4_typed_words (tag) != 2)
    panic ("%s: invalid format of sigma0 reply", __func__);
  l4_msg_store (tag, msg);
  l4_msg_get_map_item (msg, 0, &map_item);
  if (l4_is_nil_fpage (l4_map_item_snd_fpage (map_item)))
    panic ("%s: sigma0 rejected mapping", __func__);
  if (l4_address (fpage) != l4_address (l4_map_item_snd_fpage (map_item)))
    panic ("%s: sigma0 returned wrong address 0x%x (expected 0x%x)",
	   __func__, l4_address (l4_map_item_snd_fpage (map_item)),
	   l4_address (fpage));
}


/* Request an fpage of the size 2^SIZE from sigma0.  The fpage will be
   fully accessible.  */
l4_fpage_t
sigma0_get_any (unsigned int size)
{
  l4_msg_t msg;
  l4_msg_tag_t tag;
  l4_map_item_t map_item;
  l4_fpage_t fpage = l4_fpage_log2 (-1, size);

  l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE));
  l4_msg_clear (msg);
  l4_set_msg_label (msg, SIGMA0_RPC);
  l4_msg_append_word (msg, fpage);
  l4_msg_append_word (msg, L4_DEFAULT_MEMORY);
  l4_msg_load (msg);
  tag = l4_call (SIGMA0_TID);
  if (l4_ipc_failed (tag))
    panic ("%s: request failed during %s: %u", __func__,
	   l4_error_code () & 1 ? "receive" : "send",
	   (l4_error_code () >> 1) & 0x7);
  if (l4_untyped_words (tag) != 0
      || l4_typed_words (tag) != 2)
    panic ("%s: invalid format of sigma0 reply", __func__);
  l4_msg_store (tag, msg);
  l4_msg_get_map_item (msg, 0, &map_item);
  return l4_map_item_snd_fpage (map_item);
}