source: mainline/uspace/ns/ns.c@ ff3a34b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ff3a34b was 2057572, checked in by Jakub Jermar <jakub@…>, 18 years ago

The Ultimate Solution To Illegal Virtual Aliases.
It is better to avoid them completely than to fight them.
Switch the sparc64 port to 16K pages. The TLBs and TSBs
continue to operate with 8K pages only. Page tables and
other generic parts operate with 16K pages.

Because the MMU doesn't support 16K directly, each 16K
page is emulated by a pair of 8K pages. With 16K pages,
illegal aliases cannot be created in 16K D-cache.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup ns
30 * @{
31 */
32
33/**
34 * @file ns.c
35 * @brief Naming service for HelenOS IPC.
36 */
37
38
39#include <ipc/ipc.h>
40#include <ipc/ns.h>
41#include <ipc/services.h>
42#include <stdio.h>
43#include <unistd.h>
44#include <stdlib.h>
45#include <errno.h>
46#include <assert.h>
47#include <libadt/list.h>
48#include <libadt/hash_table.h>
49#include <sysinfo.h>
50#include <ddi.h>
51#include <as.h>
52
53#define NAME "NS"
54
55#define NS_HASH_TABLE_CHAINS 20
56
57static int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call);
58static int connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid);
59
60/* Static functions implementing NS hash table operations. */
61static hash_index_t ns_hash(unsigned long *key);
62static int ns_compare(unsigned long *key, hash_count_t keys, link_t *item);
63static void ns_remove(link_t *item);
64
65/** Operations for NS hash table. */
66static hash_table_operations_t ns_hash_table_ops = {
67 .hash = ns_hash,
68 .compare = ns_compare,
69 .remove_callback = ns_remove
70};
71
72/** NS hash table structure. */
73static hash_table_t ns_hash_table;
74
75/** NS hash table item. */
76typedef struct {
77 link_t link;
78 ipcarg_t service; /**< Number of the service. */
79 ipcarg_t phone; /**< Phone registered with the service. */
80 ipcarg_t in_phone_hash; /**< Incoming phone hash. */
81} hashed_service_t;
82
83static void *clockaddr = NULL;
84static void *klogaddr = NULL;
85
86static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, void **addr)
87{
88 void *ph_addr;
89
90 if (!*addr) {
91 ph_addr = (void *) sysinfo_value(name);
92 if (!ph_addr) {
93 ipc_answer_fast(callid, ENOENT, 0, 0);
94 return;
95 }
96 *addr = as_get_mappable_page(PAGE_SIZE);
97 physmem_map(ph_addr, *addr, 1, AS_AREA_READ | AS_AREA_CACHEABLE);
98 }
99 ipc_answer_fast(callid, 0, (ipcarg_t) *addr, AS_AREA_READ);
100}
101
102int main(int argc, char **argv)
103{
104 ipc_call_t call;
105 ipc_callid_t callid;
106
107 ipcarg_t retval;
108
109 if (!hash_table_create(&ns_hash_table, NS_HASH_TABLE_CHAINS, 3, &ns_hash_table_ops)) {
110 return ENOMEM;
111 }
112
113 while (1) {
114 callid = ipc_wait_for_call(&call);
115 switch (IPC_GET_METHOD(call)) {
116 case IPC_M_AS_AREA_RECV:
117 switch (IPC_GET_ARG3(call)) {
118 case SERVICE_MEM_REALTIME:
119 get_as_area(callid, &call, "clock.faddr",
120 &clockaddr);
121 break;
122 case SERVICE_MEM_KLOG:
123 get_as_area(callid, &call, "klog.faddr",
124 &klogaddr);
125 break;
126 default:
127 ipc_answer_fast(callid, ENOENT, 0, 0);
128 }
129 continue;
130 case IPC_M_PHONE_HUNGUP:
131 retval = 0;
132 break;
133 case IPC_M_CONNECT_TO_ME:
134 /*
135 * Server requests service registration.
136 */
137 retval = register_service(IPC_GET_ARG1(call), IPC_GET_ARG3(call), &call);
138 break;
139 case IPC_M_CONNECT_ME_TO:
140 /*
141 * Client requests to be connected to a service.
142 */
143 retval = connect_to_service(IPC_GET_ARG1(call), &call, callid);
144 break;
145 default:
146 retval = ENOENT;
147 break;
148 }
149 if (! (callid & IPC_CALLID_NOTIFICATION)) {
150 ipc_answer_fast(callid, retval, 0, 0);
151 }
152 }
153}
154
155/** Register service.
156 *
157 * @param service Service to be registered.
158 * @param phone phone Phone to be used for connections to the service.
159 * @param call Pointer to call structure.
160 *
161 * @return Zero on success or a value from @ref errno.h.
162 */
163int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call)
164{
165 unsigned long keys[3] = { service, call->in_phone_hash, 0 };
166 hashed_service_t *hs;
167
168 if (hash_table_find(&ns_hash_table, keys)) {
169 return EEXISTS;
170 }
171
172 hs = (hashed_service_t *) malloc(sizeof(hashed_service_t));
173 if (!hs) {
174 return ENOMEM;
175 }
176
177 link_initialize(&hs->link);
178 hs->service = service;
179 hs->phone = phone;
180 hs->in_phone_hash = call->in_phone_hash;
181 hash_table_insert(&ns_hash_table, keys, &hs->link);
182
183 return 0;
184}
185
186/** Connect client to service.
187 *
188 * @param service Service to be connected to.
189 * @param call Pointer to call structure.
190 * @param callid Call ID of the request.
191 *
192 * @return Zero on success or a value from @ref errno.h.
193 */
194int connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid)
195{
196 unsigned long keys[3] = { service, 0, 0 };
197 link_t *hlp;
198 hashed_service_t *hs;
199
200 hlp = hash_table_find(&ns_hash_table, keys);
201 if (!hlp) {
202 return ENOENT;
203 }
204 hs = hash_table_get_instance(hlp, hashed_service_t, link);
205 return ipc_forward_fast(callid, hs->phone, 0, 0);
206}
207
208/** Compute hash index into NS hash table.
209 *
210 * @param key Pointer keys. However, only the first key (i.e. service number)
211 * is used to compute the hash index.
212 * @return Hash index corresponding to key[0].
213 */
214hash_index_t ns_hash(unsigned long *key)
215{
216 assert(key);
217 return *key % NS_HASH_TABLE_CHAINS;
218}
219
220/** Compare a key with hashed item.
221 *
222 * This compare function always ignores the third key.
223 * It exists only to make it possible to remove records
224 * originating from connection with key[1] in_phone_hash
225 * value. Note that this is close to being classified
226 * as a nasty hack.
227 *
228 * @param key Array of keys.
229 * @param keys Must be lesser or equal to 3.
230 * @param item Pointer to a hash table item.
231 * @return Non-zero if the key matches the item, zero otherwise.
232 */
233int ns_compare(unsigned long key[], hash_count_t keys, link_t *item)
234{
235 hashed_service_t *hs;
236
237 assert(key);
238 assert(keys <= 3);
239 assert(item);
240
241 hs = hash_table_get_instance(item, hashed_service_t, link);
242
243 if (keys == 2)
244 return key[1] == hs->in_phone_hash;
245 else
246 return key[0] == hs->service;
247}
248
249/** Perform actions after removal of item from the hash table.
250 *
251 * @param item Item that was removed from the hash table.
252 */
253void ns_remove(link_t *item)
254{
255 assert(item);
256 free(hash_table_get_instance(item, hashed_service_t, link));
257}
258
259/**
260 * @}
261 */
Note: See TracBrowser for help on using the repository browser.