OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [cmds/] [hdbug.c] - Blame information for rev 707

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcus.erl
/*
2
    hdbug.c -- harddisk debugging
3
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
4
 
5
    This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
#include "support.h"
23
#include "common.h"
24
#include "dos.h"
25
#include "hdbug.h"
26
#include <ctype.h>
27
 
28
static int hdbug_num_commands;
29
static command_struct hdbug_command[MAX_HDBUG_COMMANDS];
30
 
31
static struct dosparam _dos_params;
32
static struct dosparam *dos_params = &_dos_params;
33
 
34
/**********************************************************************/
35
/*                                                                    */
36
/*      H D B U G                                                     */
37
/*                                                                    */
38
/**********************************************************************/
39
/*
40
        H D B U G _ I N I T
41
 
42
        initializes the ata core, mounts the DOS file system, and
43
        provides methods for accessing DOS drives
44
*/
45 406 julius
void module_hdbug_init(void)
46 2 marcus.erl
{
47 406 julius
        hdbug_num_commands = 0;
48 2 marcus.erl
 
49 406 julius
        register_command("hdbug", "<device> [<mode>]",
50
                         "Opens ata device <device> & mounts DOS filesystem",
51
                         hdbug_mount_cmd);
52
        register_hdbug_command("umount", "",
53
                               "Unmounts DOS filesystem & Closes device",
54
                               hdbug_umount_cmd);
55 2 marcus.erl
 
56 406 julius
        register_hdbug_command("dir", "", "dos 'dir' command.", hdbug_dir_cmd);
57
        register_hdbug_command("cd", "", "dos 'cd' command.", hdbug_cd_cmd);
58
        register_hdbug_command("help", "", "Display this help message",
59
                               hdbug_help);
60
        register_hdbug_command("exit", "", "Exit hdbug and return to ORPmon",
61
                               hdbug_umount_cmd);
62 2 marcus.erl
}
63
 
64
/*
65
 The next code is graceously taken from the "common.c" file
66
 and slightly modified.
67
 
68
 Better would be if we could access the routines in 'common.c'
69
 directly, using our own set of commands.
70
*/
71
 
72
/* Process command-line, generate arguments */
73
int hdbug_mon_command(void)
74
{
75 406 julius
        char c = '\0';
76
        char str[1000];
77
        char *pstr = str;
78
        char *command_str;
79
        char *argv[20];
80
        int argc = 0;
81 2 marcus.erl
 
82 406 julius
        /* Show prompt */
83
        printf("\nhdbug> ");
84 2 marcus.erl
 
85 406 julius
        /* Get characters from UART */
86
        c = getc();
87
        while (c != '\r' && c != '\f' && c != '\n') {
88
                if (c == '\b')
89
                        pstr--;
90
                else
91
                        *pstr++ = c;
92
                putc(c);
93
                c = getc();
94
        }
95
        *pstr = '\0';
96
        printf("\n");
97 2 marcus.erl
 
98 406 julius
        /* Skip leading blanks */
99
        pstr = str;
100
        while (isspace(*pstr))
101
                pstr++;
102 2 marcus.erl
 
103 406 julius
        /* Get command from the string */
104
        command_str = pstr;
105 2 marcus.erl
 
106 406 julius
        while (1) {
107
                /* Go to next argument */
108
                while (isgraph(*pstr))
109
                        pstr++;
110
                if (*pstr) {
111
                        *pstr++ = '\0';
112
                        while (isspace(*pstr))
113
                                pstr++;
114
                        argv[argc++] = pstr;
115
                } else
116
                        break;
117
        }
118 2 marcus.erl
 
119 406 julius
        return execute_hdbug_command(command_str, argc, argv);
120 2 marcus.erl
}
121
 
122
int execute_hdbug_command(char *command_str, int argc, char **argv)
123
{
124 406 julius
        int i, found = 0;
125 2 marcus.erl
 
126 406 julius
        for (i = 0; i < hdbug_num_commands; i++)
127
                if (!strcmp(command_str, hdbug_command[i].name)) {
128
                        switch (hdbug_command[i].func(argc, argv)) {
129
                        case -1:
130
                                printf
131
                                    ("Missing/wrong parameters, usage: %s %s\n",
132
                                     hdbug_command[i].name,
133
                                     hdbug_command[i].params);
134
                                break;
135 2 marcus.erl
 
136 406 julius
                        case -2:
137
                                return -1;
138
                        }
139 2 marcus.erl
 
140 406 julius
                        found++;
141
                        break;
142
                }
143 2 marcus.erl
 
144 406 julius
        if (!found)
145
                printf("Unknown command. Type 'hdbug help' for help.\n");
146 2 marcus.erl
 
147 406 julius
        return 0;
148 2 marcus.erl
}
149
 
150 406 julius
void register_hdbug_command(const char *name, const char *params,
151
                            const char *help, int (*func) (int argc,
152
                                                           char *argv[]))
153 2 marcus.erl
{
154 406 julius
        if (hdbug_num_commands < MAX_HDBUG_COMMANDS) {
155
                hdbug_command[hdbug_num_commands].name = name;
156
                hdbug_command[hdbug_num_commands].params = params;
157
                hdbug_command[hdbug_num_commands].help = help;
158
                hdbug_command[hdbug_num_commands].func = func;
159
                hdbug_num_commands++;
160
        } else
161
                printf
162
                    ("hdbug-command '%s' ignored; MAX_COMMANDS limit reached\n",
163
                     name);
164 2 marcus.erl
}
165
 
166
int hdbug_help(int argc, char **argv)
167
{
168 406 julius
        int i;
169 2 marcus.erl
 
170 406 julius
        for (i = 0; i < hdbug_num_commands; i++)
171
                printf("%-15s %-17s -%s\n", hdbug_command[i].name,
172
                       hdbug_command[i].params, hdbug_command[i].help);
173 2 marcus.erl
 
174 406 julius
        return 0;
175 2 marcus.erl
}
176
 
177
/**********************************************************************/
178
/*                                                                    */
179
/*     H D B U G   C O M M A N D S E T                                */
180
/*                                                                    */
181
/**********************************************************************/
182
 
183
/*
184
        H D B U G _ M O U N T
185
 
186
        opens the ata-device and mounts the dos filesystem
187
*/
188
int hdbug_mount_cmd(int argc, char **argv)
189
{
190 406 julius
        int error;
191 2 marcus.erl
 
192 406 julius
        if (argc != 2)
193
                return -1;
194 2 marcus.erl
 
195 406 julius
        /* try to open the requested device (read-only)                     */
196
        dos_params->inode.i_rdev = (ATA_BASE_ADDR >> 16) | (**argv - '0');
197
        dos_params->filp.f_mode = FMODE_READ;
198 2 marcus.erl
 
199 406 julius
        /* open device                                                      */
200
        if ((error = dos_open(dos_params))) {
201
                switch (error) {
202
                case EINVAL:
203
                        printf("Error, device busy.\n");        /* standard response to EINVAL */
204
                        break;
205 2 marcus.erl
 
206 406 julius
                case EIOCTLIARG:
207
                        printf("Error, invalid IOCTL call.\n");
208
                        break;
209 2 marcus.erl
 
210 406 julius
                case EOPENIDEV:
211
                        printf("Error, invalid device.\n");
212
                        break;
213 2 marcus.erl
 
214 406 julius
                case EOPENIHOST:
215
                        printf("Error, ata host controller not found.\n");
216
                        break;
217 2 marcus.erl
 
218 406 julius
                case EOPENNODEV:
219
                        printf("Error, ata-device not found.\n");
220
                        break;
221 2 marcus.erl
 
222 406 julius
                default:
223
                        printf("Unkown error.\n");
224
                        break;
225
                }
226
        } else {
227
                printf("directory startsector: 0x%08lX\n", dos_params->ssector);
228
                printf("cluster startsector  : 0x%08lX\n", dos_params->csector);
229
                printf("cluster startentry   : 0x%08lX\n", dos_params->sentry);
230 2 marcus.erl
 
231 406 julius
                /* device is opened, filesystem is mounted, start command prompt  */
232
                while (!hdbug_mon_command()) ;
233
        }
234 2 marcus.erl
 
235 406 julius
        return 0;
236 2 marcus.erl
}
237
 
238
/*
239
        H D B U G _ U M O U N T
240
 
241
        unmounts the dos filesystem and closes the ata-device
242
*/
243
int hdbug_umount_cmd(int argc, char **argv)
244
{
245 406 julius
        dos_release(dos_params);
246 2 marcus.erl
 
247 406 julius
        return -2;
248 2 marcus.erl
}
249
 
250
/*
251
        H D B U G _ C D
252
*/
253
int hdbug_cd_cmd(int argc, char **argv)
254
{
255 406 julius
        struct dos_dir_entry *entry;
256 2 marcus.erl
 
257 406 julius
        switch (argc) {
258
        case 0:
259
                /* display present working directory                            */
260
                printf("FIXME: present working directory\n");
261
                return 0;
262 2 marcus.erl
 
263 406 julius
        case 1:
264
                break;
265 2 marcus.erl
 
266 406 julius
        default:
267
                printf("Too many arguments.\n");
268
                return 0;
269
        }
270 2 marcus.erl
 
271 406 julius
        /* search for the requested directory                               */
272
        if (!(entry = dos_dir_find_entry(dos_params, *argv))) {
273
                printf("The system cannot find the specified path.\n");
274
                return 0;
275
        }
276 2 marcus.erl
 
277 406 julius
        return 0;
278 2 marcus.erl
}
279
 
280
/*
281
        H D B U G _ D I R
282
*/
283
int hdbug_dir_cmd(int argc, char **argv)
284
{
285 406 julius
        register int i;
286 2 marcus.erl
 
287 406 julius
        /* read the directory structures from the current directory
288
           and display the results                                        */
289 2 marcus.erl
 
290 406 julius
        /* TODO: Add sub-directories */
291 2 marcus.erl
 
292 406 julius
        /* get first cluster of current directory                         */
293
        dos_dir_cluster_reset(dos_params);
294 2 marcus.erl
 
295 406 julius
        for (i = 0; i < dos_params->root_entries; i++)
296
                hdbug_dir_print(dos_dir_get_entry(dos_params, i));
297 2 marcus.erl
 
298 406 julius
        return 0;
299 2 marcus.erl
}
300
 
301
int hdbug_dir_print(struct dos_dir_entry *entry)
302
{
303 406 julius
        unsigned long ltmp;
304
        unsigned short stmp;
305 2 marcus.erl
 
306 406 julius
        char txt[9];
307 2 marcus.erl
 
308 406 julius
        switch (entry->name[0]) {
309
        case 0x00:
310
                /* empty entry */
311
                break;
312 2 marcus.erl
 
313 406 julius
        case 0xe5:
314
                /* deleted/removed entry */
315
                break;
316 2 marcus.erl
 
317 406 julius
        default:
318
                /* check if entry is a label                                    */
319
                if (entry->attribute & ATT_LAB) {
320
                        printf("LABEL: ");
321
                        memcpy(txt, entry->name, 8);
322
                        txt[8] = '\0';
323
                        printf("%s", txt);
324
                        memcpy(txt, entry->ext, 3);
325
                        txt[3] = '\0';
326
                        printf("%s\n", txt);
327
                } else {
328
                        /* display date & time                                          */
329
                        stmp = entry->date;
330
                        swap(&stmp, sizeof(short));
331
                        printf("%02d-%02d-%4d  ", stmp & 0x1f,
332
                               (stmp >> 5) & 0xf,
333
                               ((stmp >> 9) & 0xffff) + 1980);
334 2 marcus.erl
 
335 406 julius
                        stmp = entry->time;
336
                        swap(&stmp, sizeof(short));
337
                        printf("%02d:%02d  ", (stmp >> 11) & 0x1f,
338
                               (stmp >> 5) & 0x3f);
339 2 marcus.erl
 
340 406 julius
                        /* display directory bit                                        */
341
                        printf("%s  ",
342
                               entry->attribute & ATT_DIR ? "<DIR>" : "     ");
343 2 marcus.erl
 
344 406 julius
                        /* display filesize                                             */
345
                        ltmp = entry->size;
346
                        swap(&ltmp, sizeof(unsigned long));
347
                        printf("%12ld  ", ltmp);
348 2 marcus.erl
 
349 406 julius
                        /* replace the first 'space' in the name by an null char        */
350
                        *(char *)memchr(entry->name, 0x20, 8) = '\0';
351
                        printf("%s", entry->name);
352 2 marcus.erl
 
353 406 julius
                        /* add extension                                                */
354
                        if (entry->ext[0] != 0x20) {
355
                                printf(".%3s", entry->ext);
356
                        }
357 2 marcus.erl
 
358 406 julius
                        printf("\n");
359
                        break;
360
                }
361
        }
362 2 marcus.erl
 
363 406 julius
        return 0;
364 2 marcus.erl
}
365
 
366
/*
367
        H D B U G   T O O L S
368
*/
369
inline void *swap(void *var, size_t size)
370
{
371 406 julius
        switch (size) {
372
        case 1:
373
                return var;
374 2 marcus.erl
 
375 406 julius
        case 2:
376
                {
377
                        unsigned short p = *(unsigned short *)var;
378
                        *(unsigned short *)var = (p << 8) | (p >> 8);
379
                        return var;
380
                }
381 2 marcus.erl
 
382 406 julius
        case 4:
383
                {
384
                        unsigned long *p = (unsigned long *)var;
385
                        *p = (*p << 24) | ((*p & 0x0000ff00) << 8) |
386
                            ((*p & 0x00ff0000) >> 8) | (*p >> 24);
387
                        return var;
388
                }
389 2 marcus.erl
 
390 406 julius
        default:
391
                return NULL;
392
        }
393 2 marcus.erl
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.