2 Copyright 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Emergency console launcher for AROS
9 #include <aros/debug.h>
11 #include <aros/asmcall.h>
12 #include <dos/dosextens.h>
13 #include <dos/stdio.h>
15 #include <exec/resident.h>
16 #include <graphics/modeid.h>
17 #include <utility/tagitem.h>
18 #include <libraries/expansion.h>
20 #include <proto/exec.h>
21 #include <proto/dos.h>
22 #include <proto/graphics.h>
23 #include <proto/alib.h>
24 #include <proto/expansion.h>
26 #include LC_LIBDEFS_FILE
28 /********* ECON: DOS Handler
30 * ECON: - interactive file, accesing the Exec/Raw* functions
31 * ECON:AROS.boot - synthetic file, to allow AROS to boot from ECON:
34 static void replyPkt(struct DosPacket
*dp
)
41 mn
->mn_Node
.ln_Name
= (char*)dp
;
42 dp
->dp_Port
= &((struct Process
*)FindTask(NULL
))->pr_MsgPort
;
46 struct econsole_file
{
49 SIPTR (*ef_Read
)(APTR buff
, SIPTR len
, SIPTR
*actual
);
50 SIPTR (*ef_Write
)(CONST_APTR buff
, SIPTR len
, SIPTR
*actual
);
51 SIPTR (*ef_ExamineFH
)(struct FileInfoBlock
*fib
, SIPTR
*actual
);
54 SIPTR
Raw_Read(APTR buff
, SIPTR len
, SIPTR
*err
)
59 D(bug("%s: buff=%p, len=%d\n", __func__
, buff
, len
));
60 while (actual
< len
) {
61 LONG c
= RawMayGetChar();
67 /* Trivial line editing */
69 case '\b': /* Backspace */
70 if ((APTR
)cp
> buff
) {
96 SIPTR
Raw_Write(CONST_APTR buff
, SIPTR len
, SIPTR
*err
)
99 CONST UBYTE
*cp
= buff
;
101 D(bug("%s: buff=%p, len=%d\n", __func__
, buff
, len
));
102 for (actual
= 0; actual
< len
; actual
++, cp
++) {
110 SIPTR
Raw_ExamineFH(struct FileInfoBlock
*fib
, SIPTR
*errcode
)
112 memset(fib
, 0, sizeof(*fib
));
113 fib
->fib_Protection
= FIBF_WRITE
| FIBF_READ
;
119 CONST UBYTE CONST Boot_Data
[] = AROS_CPU
;
121 SIPTR
Boot_Read(APTR buff
, SIPTR len
, SIPTR
*err
)
126 D(bug("%s: len=%d \"%s\"\n", __func__
, len
, Boot_Data
));
127 for (actual
= 0; actual
< len
; actual
++, cp
++) {
128 if (Boot_Data
[actual
] == 0)
130 *cp
= Boot_Data
[actual
];
137 SIPTR
Boot_Write(CONST_APTR buff
, SIPTR len
, SIPTR
*err
)
139 *err
= ERROR_WRITE_PROTECTED
;
143 SIPTR
Boot_ExamineFH(struct FileInfoBlock
*fib
, SIPTR
*errcode
)
145 memset(fib
, 0, sizeof(*fib
));
146 fib
->fib_FileName
[0] = strlen("AROS.boot");
147 CopyMem("AROS.boot", &fib
->fib_FileName
[1], fib
->fib_FileName
[0] + 1);
148 fib
->fib_Protection
= FIBF_READ
;
149 fib
->fib_Size
= sizeof(Boot_Data
) - 1;
155 const struct econsole_file econsole_files
[] = {
156 { .ef_Name
= "", .ef_Interactive
= TRUE
,
157 .ef_Read
= Raw_Read
, .ef_Write
= Raw_Write
,
158 .ef_ExamineFH
= Raw_ExamineFH
160 { .ef_Name
= "AROS.boot", .ef_Interactive
= FALSE
,
161 .ef_Read
= Boot_Read
, .ef_Write
= Boot_Write
,
162 .ef_ExamineFH
= Boot_ExamineFH
167 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
170 const struct econsole_file
*econsole_file_of(BSTR bname
, SIPTR
*errcode
)
174 int blen
= AROS_BSTR_strlen(bname
);
176 name
= AllocMem(blen
+ 1, MEMF_ANY
);
177 CopyMem(AROS_BSTR_ADDR(bname
), name
, blen
);
180 file
= strchr(name
, ':');
186 D(bug("%s: bname=%b, name=%s, file=%s\n", __func__
, bname
, name
, file
));
187 for (i
= 0; i
< ARRAY_SIZE(econsole_files
); i
++) {
188 if (strcmp(econsole_files
[i
].ef_Name
, file
) == 0) {
189 FreeMem(name
, blen
+ 1);
191 return &econsole_files
[i
];
195 FreeMem(name
, blen
+ 1);
196 *errcode
= ERROR_OBJECT_NOT_FOUND
;
200 LONG
econ_handler(struct ExecBase
*SysBase
)
202 struct DosPacket
*dp
;
205 struct FileHandle
*fh
;
206 const struct econsole_file
*efile
;
207 struct DeviceNode
*dn
;
209 mp
= &((struct Process
*)FindTask(NULL
))->pr_MsgPort
;
213 dp
= (struct DosPacket
*)(GetMsg(mp
)->mn_Node
.ln_Name
);
215 dn
= ((struct DeviceNode
*)BADDR(dp
->dp_Arg3
));
219 dp
->dp_Res1
= DOSTRUE
;
223 D(bug("%s: started\n", __func__
));
227 dp
= (struct DosPacket
*)(GetMsg(mp
)->mn_Node
.ln_Name
);
228 D(bug("%s: type=%d\n", __func__
, dp
->dp_Type
));
230 switch (dp
->dp_Type
) {
231 case ACTION_LOCATE_OBJECT
:
232 if ((efile
= econsole_file_of((BSTR
)dp
->dp_Arg2
, &dp
->dp_Res2
))) {
233 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
234 struct FileLock
*fl
= AllocMem(sizeof(*fl
), MEMF_PUBLIC
| MEMF_CLEAR
);
236 fl
->fl_Key
= (IPTR
)efile
;
237 fl
->fl_Access
= dp
->dp_Arg3
;
239 fl
->fl_Volume
= MKBADDR(dn
);
240 dp
->dp_Res1
= (SIPTR
)MKBADDR(fl
);
242 dp
->dp_Res1
= DOSFALSE
;
245 case ACTION_FH_FROM_LOCK
:
247 struct FileLock
*fl
= BADDR(dp
->dp_Arg2
);
248 efile
= (const struct econsole_file
*)fl
->fl_Key
;
249 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
250 fh
= BADDR(dp
->dp_Arg1
);
251 fh
->fh_Arg1
= (SIPTR
)efile
;
253 fh
->fh_Interactive
= efile
->ef_Interactive
;
254 FreeMem(fl
, sizeof(*fl
));
257 dp
->dp_Res2
= ERROR_OBJECT_NOT_FOUND
;
259 dp
->dp_Res1
= dp
->dp_Res2
? DOSFALSE
: DOSTRUE
;
261 case ACTION_COPY_DIR_FH
:
263 struct FileLock
*fl
= AllocMem(sizeof(*fl
), MEMF_PUBLIC
| MEMF_CLEAR
);
264 efile
= (const struct econsole_file
*)dp
->dp_Arg1
;
265 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
267 fl
->fl_Key
= (SIPTR
)efile
;
268 fl
->fl_Access
= dp
->dp_Arg3
;
270 fl
->fl_Volume
= MKBADDR(dn
);
271 dp
->dp_Res1
= (SIPTR
)MKBADDR(fl
);
274 dp
->dp_Res1
= DOSFALSE
;
275 dp
->dp_Res2
= ERROR_OBJECT_NOT_FOUND
;
278 case ACTION_FREE_LOCK
:
280 struct FileLock
*fl
= BADDR(dp
->dp_Arg1
);
281 FreeMem(fl
, sizeof(*fl
));
283 dp
->dp_Res1
= DOSTRUE
;
286 case ACTION_FINDINPUT
:
287 case ACTION_FINDOUTPUT
:
288 case ACTION_FINDUPDATE
:
289 if ((efile
= econsole_file_of((BSTR
)dp
->dp_Arg3
, &dp
->dp_Res2
))) {
290 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
291 fh
= BADDR(dp
->dp_Arg1
);
292 fh
->fh_Arg1
= (SIPTR
)efile
;
294 fh
->fh_Interactive
= efile
->ef_Interactive
;
296 dp
->dp_Res1
= efile
? DOSTRUE
: DOSFALSE
;
299 if ((efile
= (const struct econsole_file
*)dp
->dp_Arg1
)) {
300 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
301 dp
->dp_Res1
= efile
->ef_Read((APTR
)dp
->dp_Arg2
, dp
->dp_Arg3
, &dp
->dp_Res2
);
303 dp
->dp_Res1
= DOSFALSE
;
304 dp
->dp_Res2
= ERROR_OBJECT_WRONG_TYPE
;
308 if ((efile
= (const struct econsole_file
*)dp
->dp_Arg1
)) {
309 D(bug("%s: efile=%p (%s)\n", __func__
, efile
, efile
->ef_Name
));
310 dp
->dp_Res1
= efile
->ef_Write((CONST_APTR
)dp
->dp_Arg2
, dp
->dp_Arg3
, &dp
->dp_Res2
);
312 dp
->dp_Res1
= DOSFALSE
;
313 dp
->dp_Res2
= ERROR_OBJECT_WRONG_TYPE
;
316 case ACTION_EXAMINE_FH
:
317 if ((efile
= (const struct econsole_file
*)dp
->dp_Arg1
)) {
318 dp
->dp_Res1
= efile
->ef_ExamineFH((struct FileInfoBlock
*)BADDR(dp
->dp_Arg2
), &dp
->dp_Res2
);
320 dp
->dp_Res1
= DOSFALSE
;
321 dp
->dp_Res2
= ERROR_OBJECT_WRONG_TYPE
;
325 dp
->dp_Res1
= DOSTRUE
;
329 dp
->dp_Res1
= DOSTRUE
;
334 dp
->dp_Res1
= DOSFALSE
;
335 dp
->dp_Res2
= ERROR_ACTION_NOT_KNOWN
;
338 D(bug("%s: Type %d, Res1=%p, Res2=%p\n", __func__
, dp
->dp_Type
, dp
->dp_Res1
, dp
->dp_Res2
));
341 /* ACTION_DIE ends up here... */
342 D(bug("%s: Exiting\n", __func__
));