2 * Creation Date: <2003/12/03 22:10:45 samuel>
3 * Time-stamp: <2004/01/07 19:17:45 samuel>
9 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
18 #include "libopenbios/bindings.h"
19 #include "libopenbios/load.h"
20 #include "libc/diskio.h"
21 #include "libc/vsprintf.h"
24 //#define DEBUG_DISK_LABEL
26 #ifdef DEBUG_DISK_LABEL
27 #define DPRINTF(fmt, args...) \
28 do { printk("DISK-LABEL - %s: " fmt, __func__ , ##args); } while (0)
30 #define DPRINTF(fmt, args...) do { } while (0)
38 ucell offs_hi
, offs_lo
;
39 ucell size_hi
, size_lo
;
41 int type
; /* partition type or -1 */
44 phandle_t filesystem_ph
;
47 DECLARE_NODE( dlabel
, 0, sizeof(dlabel_info_t
), "/packages/disk-label" );
52 dlabel_close( __attribute__((unused
))dlabel_info_t
*di
)
58 dlabel_open( dlabel_info_t
*di
)
66 path
= my_args_copy();
68 DPRINTF("dlabel-open '%s'\n", path
);
72 /* Find parent methods */
73 di
->filesystem_ph
= 0;
74 di
->parent_seek_xt
= find_parent_method("seek");
75 di
->parent_tell_xt
= find_parent_method("tell");
76 di
->parent_read_xt
= find_parent_method("read");
78 /* Read first block from parent device */
80 call_package(di
->parent_seek_xt
, my_parent());
85 call_package(di
->parent_read_xt
, my_parent());
87 if (status
!= sizeof(block0
))
90 /* Find partition handler */
91 PUSH( (ucell
)block0
);
92 selfword("find-part-handler");
95 /* We found a suitable partition handler, so interpose it */
96 DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx
"\n", ph
);
104 /* unknown (or missing) partition map,
108 DPRINTF("Unknown or missing partition map; trying whole disk\n");
110 /* Probe for filesystem from start of device */
112 PUSH_ih( my_self() );
113 selfword("find-filesystem");
116 /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */
117 di
->filesystem_ph
= ph
;
119 DPRINTF("Located filesystem with ph " FMT_ucellx
"\n", ph
);
120 DPRINTF("path: %s length: %d\n", path
, strlen(path
));
122 if (path
&& strlen(path
)) {
123 DPRINTF("INTERPOSE!\n");
129 } else if (path
&& strcmp(path
, "%BOOT") != 0) {
146 /* ( addr len -- actual ) */
148 dlabel_read( dlabel_info_t
*di
)
150 /* Call back up to parent */
151 call_package(di
->parent_read_xt
, my_parent());
154 /* ( pos.d -- status ) */
156 dlabel_seek( dlabel_info_t
*di
)
158 /* Call back up to parent */
159 call_package(di
->parent_seek_xt
, my_parent());
162 /* ( -- filepos.d ) */
164 dlabel_tell( dlabel_info_t
*di
)
166 /* Call back up to parent */
167 call_package(di
->parent_tell_xt
, my_parent());
170 /* ( addr len -- actual ) */
172 dlabel_write( __attribute__((unused
)) dlabel_info_t
*di
)
178 /* ( addr -- size ) */
180 dlabel_load( __attribute__((unused
)) dlabel_info_t
*di
)
182 /* Try the load method of the part package */
183 #ifdef DEBUG_DISK_LABEL
188 #ifdef DEBUG_DISK_LABEL
194 DPRINTF("load invoked with address %p\n", buf
);
196 /* If we have a partition handle, invoke the load word on it */
198 xt
= find_ih_method("load", di
->part_ih
);
200 forth_printf("load currently not implemented for ihandle " FMT_ucellx
"\n", di
->part_ih
);
205 DPRINTF("calling load on ihandle " FMT_ucellx
"\n", di
->part_ih
);
207 call_package(xt
, di
->part_ih
);
209 /* Otherwise attempt load directly on the raw disk */
210 DPRINTF("calling load on raw disk ihandle " FMT_ucellx
"\n", my_self());
216 /* ( pathstr len -- ) */
218 dlabel_dir( dlabel_info_t
*di
)
220 if ( di
->filesystem_ph
) {
223 PUSH( di
->filesystem_ph
);
224 fword("find-method");
228 forth_printf("disk-label: Unable to determine filesystem\n");
234 NODE_METHODS( dlabel
) = {
235 { "open", dlabel_open
},
236 { "close", dlabel_close
},
237 { "load", dlabel_load
},
238 { "read", dlabel_read
},
239 { "write", dlabel_write
},
240 { "seek", dlabel_seek
},
241 { "tell", dlabel_tell
},
242 { "dir", dlabel_dir
},
246 disklabel_init( void )
248 REGISTER_NODE( dlabel
);