Subversion Repositories HelenOS

Rev

Rev 3225 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3225 Rev 3790
1
/*
1
/*
2
 * Copyright (c) 2006 Jakub Vana
2
 * Copyright (c) 2006 Jakub Vana
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup generic
29
/** @addtogroup generic
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <sysinfo/sysinfo.h>
35
#include <sysinfo/sysinfo.h>
36
#include <mm/slab.h>
36
#include <mm/slab.h>
37
#include <print.h>
37
#include <print.h>
38
#include <syscall/copy.h>
38
#include <syscall/copy.h>
39
 
39
 
40
sysinfo_item_t *_root = NULL;
40
sysinfo_item_t *_root = NULL;
41
 
41
 
42
 
42
 
43
static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
43
static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
44
{
44
{
45
    if (subtree == NULL)
45
    if (subtree == NULL)
46
        return NULL;
46
        return NULL;
47
   
47
   
48
    while (subtree != NULL) {
48
    while (subtree != NULL) {
49
        int i = 0;
49
        int i = 0;
50
        char *a = (char *) name;
50
        char *a = (char *) name;
51
        char *b = subtree->name;
51
        char *b = subtree->name;
52
       
52
       
53
        while ((a[i] == b[i]) && (b[i]))
53
        while ((a[i] == b[i]) && (b[i]))
54
            i++;
54
            i++;
55
       
55
       
56
        if ((!a[i]) && (!b[i]))  /* Last name in path matches */
56
        if ((!a[i]) && (!b[i]))  /* Last name in path matches */
57
            return subtree;
57
            return subtree;
58
       
58
       
59
        if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
59
        if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
60
            if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
60
            if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
61
                return sysinfo_find_item(a + i + 1, subtree->subinfo.table);
61
                return sysinfo_find_item(a + i + 1, subtree->subinfo.table);
62
           
62
           
63
            //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
63
            //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
64
            //  return NULL; 
64
            //  return NULL; 
65
           
65
           
66
            return NULL; /* No subinfo */
66
            return NULL; /* No subinfo */
67
        }
67
        }
68
        /* No matches try next */
68
        /* No matches try next */
69
        subtree = subtree->next;
69
        subtree = subtree->next;
70
        i = 0;
70
        i = 0;
71
    }
71
    }
72
    return NULL;
72
    return NULL;
73
}
73
}
74
 
74
 
75
static sysinfo_item_t *sysinfo_create_path(const char *name, sysinfo_item_t **psubtree)
75
static sysinfo_item_t *sysinfo_create_path(const char *name, sysinfo_item_t **psubtree)
76
{
76
{
77
    sysinfo_item_t *subtree;
77
    sysinfo_item_t *subtree;
78
    subtree = *psubtree;
78
    subtree = *psubtree;
79
   
79
   
80
    if (subtree == NULL) {
80
    if (subtree == NULL) {
81
        sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
81
        sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
82
        int i = 0, j;
82
        int i = 0, j;
83
           
83
           
84
        ASSERT(item);
84
        ASSERT(item);
85
        *psubtree = item;
85
        *psubtree = item;
86
        item->next = NULL;
86
        item->next = NULL;
87
        item->val_type = SYSINFO_VAL_UNDEFINED;
87
        item->val_type = SYSINFO_VAL_UNDEFINED;
88
        item->subinfo.table = NULL;
88
        item->subinfo.table = NULL;
89
 
89
 
90
        while (name[i] && (name[i] != '.'))
90
        while (name[i] && (name[i] != '.'))
91
            i++;
91
            i++;
92
           
92
           
93
        item->name = malloc(i, 0);
93
        item->name = malloc(i, 0);
94
        ASSERT(item->name);
94
        ASSERT(item->name);
95
 
95
 
96
        for (j = 0; j < i; j++)
96
        for (j = 0; j < i; j++)
97
            item->name[j] = name[j];
97
            item->name[j] = name[j];
98
        item->name[j] = 0;
98
        item->name[j] = 0;
99
           
99
           
100
        if (name[i]) { /* =='.' */
100
        if (name[i]) { /* =='.' */
101
            item->subinfo_type = SYSINFO_SUBINFO_TABLE;
101
            item->subinfo_type = SYSINFO_SUBINFO_TABLE;
102
            return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
102
            return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
103
        }
103
        }
104
        item->subinfo_type = SYSINFO_SUBINFO_NONE;
104
        item->subinfo_type = SYSINFO_SUBINFO_NONE;
105
        return item;
105
        return item;
106
    }
106
    }
107
 
107
 
108
    while (subtree != NULL) {
108
    while (subtree != NULL) {
109
        int i = 0, j;
109
        int i = 0, j;
110
        char *a = (char *) name;
110
        char *a = (char *) name;
111
        char *b = subtree->name;
111
        char *b = subtree->name;
112
       
112
       
113
        while ((a[i] == b[i]) && (b[i]))
113
        while ((a[i] == b[i]) && (b[i]))
114
            i++;
114
            i++;
115
       
115
       
116
        if ((!a[i]) && (!b[i])) /* Last name in path matches */
116
        if ((!a[i]) && (!b[i])) /* Last name in path matches */
117
            return subtree;
117
            return subtree;
118
       
118
       
119
        if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
119
        if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
120
            if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
120
            if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
121
                return sysinfo_create_path(a + i + 1, &(subtree->subinfo.table));
121
                return sysinfo_create_path(a + i + 1, &(subtree->subinfo.table));
122
           
122
           
123
            if (subtree->subinfo_type == SYSINFO_SUBINFO_NONE) {
123
            if (subtree->subinfo_type == SYSINFO_SUBINFO_NONE) {
124
                subtree->subinfo_type = SYSINFO_SUBINFO_TABLE;
124
                subtree->subinfo_type = SYSINFO_SUBINFO_TABLE;
125
                return sysinfo_create_path(a + i + 1,&(subtree->subinfo.table));
125
                return sysinfo_create_path(a + i + 1,&(subtree->subinfo.table));
126
            }
126
            }
127
           
127
           
128
            //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
128
            //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
129
            //  return NULL; 
129
            //  return NULL; 
130
           
130
           
131
            return NULL;
131
            return NULL;
132
        }
132
        }
133
        /* No matches try next or create new*/
133
        /* No matches try next or create new*/
134
        if (subtree->next == NULL) {
134
        if (subtree->next == NULL) {
135
            sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
135
            sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
136
           
136
           
137
            ASSERT(item);
137
            ASSERT(item);
138
            subtree->next = item;
138
            subtree->next = item;
139
            item->next = NULL;
139
            item->next = NULL;
140
            item->val_type = SYSINFO_VAL_UNDEFINED;
140
            item->val_type = SYSINFO_VAL_UNDEFINED;
141
            item->subinfo.table = NULL;
141
            item->subinfo.table = NULL;
142
 
142
 
143
            i = 0;
143
            i = 0;
144
            while (name[i] && (name[i] != '.'))
144
            while (name[i] && (name[i] != '.'))
145
                i++;
145
                i++;
146
 
146
 
147
            item->name = malloc(i, 0);
147
            item->name = malloc(i, 0);
148
            ASSERT(item->name);
148
            ASSERT(item->name);
149
           
149
           
150
            for (j = 0; j < i; j++)
150
            for (j = 0; j < i; j++)
151
                item->name[j] = name[j];
151
                item->name[j] = name[j];
152
           
152
           
153
            item->name[j] = 0;
153
            item->name[j] = 0;
154
 
154
 
155
            if(name[i]) { /* =='.' */
155
            if(name[i]) { /* =='.' */
156
                item->subinfo_type = SYSINFO_SUBINFO_TABLE;
156
                item->subinfo_type = SYSINFO_SUBINFO_TABLE;
157
                return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
157
                return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
158
            }
158
            }
159
            item->subinfo_type = SYSINFO_SUBINFO_NONE;
159
            item->subinfo_type = SYSINFO_SUBINFO_NONE;
160
            return item;
160
            return item;
161
        } else {
161
        } else {
162
            subtree = subtree->next;
162
            subtree = subtree->next;
163
            i = 0;
163
            i = 0;
164
        }  
164
        }  
165
    }
165
    }
-
 
166
 
166
    panic("Not reached\n");
167
    panic("Not reached.");
167
    return NULL;
168
    return NULL;
168
}
169
}
169
 
170
 
170
void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
171
void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
171
{
172
{
172
    if (root == NULL)
173
    if (root == NULL)
173
        root = &_root;
174
        root = &_root;
174
   
175
   
175
    /* If already created create only returns pointer
176
    /* If already created create only returns pointer
176
       If not, create it */
177
       If not, create it */
177
    sysinfo_item_t *item = sysinfo_create_path(name, root);
178
    sysinfo_item_t *item = sysinfo_create_path(name, root);
178
   
179
   
179
    if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
180
    if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
180
        item->val.val = val;                  
181
        item->val.val = val;                  
181
        item->val_type = SYSINFO_VAL_VAL;
182
        item->val_type = SYSINFO_VAL_VAL;
182
    }
183
    }
183
}
184
}
184
 
185
 
185
void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
186
void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
186
{
187
{
187
    if (root == NULL)
188
    if (root == NULL)
188
        root = &_root;
189
        root = &_root;
189
   
190
   
190
    /* If already created create only returns pointer
191
    /* If already created create only returns pointer
191
       If not, create it */
192
       If not, create it */
192
    sysinfo_item_t *item = sysinfo_create_path(name, root);
193
    sysinfo_item_t *item = sysinfo_create_path(name, root);
193
   
194
   
194
    if (item != NULL) { /* If in subsystem, unable to create or return so  unable to set */
195
    if (item != NULL) { /* If in subsystem, unable to create or return so  unable to set */
195
        item->val.fn = fn;                  
196
        item->val.fn = fn;                  
196
        item->val_type = SYSINFO_VAL_FUNCTION;
197
        item->val_type = SYSINFO_VAL_FUNCTION;
197
    }
198
    }
198
}
199
}
199
 
200
 
200
 
201
 
201
void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
202
void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
202
{
203
{
203
    if (root == NULL)
204
    if (root == NULL)
204
        root = &_root;
205
        root = &_root;
205
   
206
   
206
    /* If already created create only returns pointer
207
    /* If already created create only returns pointer
207
       If not, create it */
208
       If not, create it */
208
    sysinfo_item_t *item = sysinfo_create_path(name, root);
209
    sysinfo_item_t *item = sysinfo_create_path(name, root);
209
   
210
   
210
    if (item != NULL)
211
    if (item != NULL)
211
        item->val_type = SYSINFO_VAL_UNDEFINED;
212
        item->val_type = SYSINFO_VAL_UNDEFINED;
212
}
213
}
213
 
214
 
214
 
215
 
215
void sysinfo_dump(sysinfo_item_t **proot, int depth)
216
void sysinfo_dump(sysinfo_item_t **proot, int depth)
216
{
217
{
217
    sysinfo_item_t *root;
218
    sysinfo_item_t *root;
218
    if (proot == NULL)
219
    if (proot == NULL)
219
        proot = &_root;
220
        proot = &_root;
220
   
221
   
221
    root = *proot;
222
    root = *proot;
222
   
223
   
223
    while (root != NULL) {
224
    while (root != NULL) {
224
        int i;
225
        int i;
225
        unative_t val = 0;
226
        unative_t val = 0;
226
        char *vtype = NULL;
227
        char *vtype = NULL;
227
       
228
       
228
       
229
       
229
        for (i = 0; i < depth; i++)
230
        for (i = 0; i < depth; i++)
230
            printf("  ");
231
            printf("  ");
231
       
232
       
232
        switch (root->val_type) {
233
        switch (root->val_type) {
233
        case SYSINFO_VAL_UNDEFINED:
234
        case SYSINFO_VAL_UNDEFINED:
234
            val = 0;
235
            val = 0;
235
            vtype = "UND";
236
            vtype = "UND";
236
            break;
237
            break;
237
        case SYSINFO_VAL_VAL:
238
        case SYSINFO_VAL_VAL:
238
            val = root->val.val;
239
            val = root->val.val;
239
            vtype = "VAL";
240
            vtype = "VAL";
240
            break;
241
            break;
241
        case SYSINFO_VAL_FUNCTION:
242
        case SYSINFO_VAL_FUNCTION:
242
            val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
243
            val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
243
            vtype = "FUN";
244
            vtype = "FUN";
244
            break;
245
            break;
245
        }
246
        }
246
       
247
       
247
        printf("%s    %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val,
248
        printf("%s    %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val,
248
            val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ?
249
            val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ?
249
            "NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ?
250
            "NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ?
250
            "TAB" : "FUN"));
251
            "TAB" : "FUN"));
251
       
252
       
252
        if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
253
        if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
253
            sysinfo_dump(&(root -> subinfo.table), depth + 1);
254
            sysinfo_dump(&(root -> subinfo.table), depth + 1);
254
       
255
       
255
        root = root->next;
256
        root = root->next;
256
    }
257
    }
257
}
258
}
258
 
259
 
259
sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
260
sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
260
{
261
{
261
    // TODO: Implement Subsystem subinfo (by function implemented subinfo)
262
    // TODO: Implement Subsystem subinfo (by function implemented subinfo)
262
 
263
 
263
    sysinfo_rettype_t ret = {0, false};
264
    sysinfo_rettype_t ret = {0, false};
264
 
265
 
265
    if (root == NULL)
266
    if (root == NULL)
266
        root = &_root;
267
        root = &_root;
267
   
268
   
268
    sysinfo_item_t *item = sysinfo_find_item(name, *root);
269
    sysinfo_item_t *item = sysinfo_find_item(name, *root);
269
   
270
   
270
    if (item != NULL) {
271
    if (item != NULL) {
271
        if (item->val_type == SYSINFO_VAL_UNDEFINED)
272
        if (item->val_type == SYSINFO_VAL_UNDEFINED)
272
            return ret;
273
            return ret;
273
        else
274
        else
274
            ret.valid = true;
275
            ret.valid = true;
275
       
276
       
276
        if (item->val_type == SYSINFO_VAL_VAL)
277
        if (item->val_type == SYSINFO_VAL_VAL)
277
            ret.val = item->val.val;
278
            ret.val = item->val.val;
278
        else
279
        else
279
            ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
280
            ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
280
    }
281
    }
281
    return ret;
282
    return ret;
282
}
283
}
283
 
284
 
284
#define SYSINFO_MAX_LEN 1024
285
#define SYSINFO_MAX_LEN 1024
285
 
286
 
286
unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
287
unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
287
{
288
{
288
    char *str;
289
    char *str;
289
    sysinfo_rettype_t ret = {0, 0};
290
    sysinfo_rettype_t ret = {0, 0};
290
 
291
 
291
    if (len > SYSINFO_MAX_LEN)
292
    if (len > SYSINFO_MAX_LEN)
292
        return ret.valid;
293
        return ret.valid;
293
    str = malloc(len + 1, 0);
294
    str = malloc(len + 1, 0);
294
   
295
   
295
    ASSERT(str);
296
    ASSERT(str);
296
    if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
297
    if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
297
        ret = sysinfo_get_val(str, NULL);
298
        ret = sysinfo_get_val(str, NULL);
298
   
299
   
299
    free(str);
300
    free(str);
300
    return ret.valid;
301
    return ret.valid;
301
}
302
}
302
 
303
 
303
unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
304
unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
304
{
305
{
305
    char *str;
306
    char *str;
306
    sysinfo_rettype_t ret = {0, 0};
307
    sysinfo_rettype_t ret = {0, 0};
307
   
308
   
308
    if (len > SYSINFO_MAX_LEN)
309
    if (len > SYSINFO_MAX_LEN)
309
        return ret.val;
310
        return ret.val;
310
    str = malloc(len + 1, 0);
311
    str = malloc(len + 1, 0);
311
   
312
   
312
    ASSERT(str);
313
    ASSERT(str);
313
    if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
314
    if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
314
        ret = sysinfo_get_val(str, NULL);
315
        ret = sysinfo_get_val(str, NULL);
315
   
316
   
316
    free(str);
317
    free(str);
317
    return ret.val;
318
    return ret.val;
318
}
319
}
319
 
320
 
320
/** @}
321
/** @}
321
 */
322
 */
322
 
323