1 /*
2 * Copyright 2008-2010, François Revol, revol@free.fr. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include <boot/platform.h>
8 #include <boot/stage2.h>
9 #include <boot/stdio.h>
10 #include <stdarg.h>
11
12 #include <Errors.h>
13
14 #include "toscalls.h"
15
16
17 void *gXHDIEntryPoint = NULL;
18 uint32 gXHDIVersion = 0;
19
20 NatFeatCookie *gNatFeatCookie = NULL;
21 uint32 gDebugPrintfNatFeatID = 0;
22 uint32 gBootstrapNatFeatID = 0;
23
24
25 /*! Maps TOS error codes to native errors
26 */
27 extern "C" status_t
toserror(int32 err)28 toserror(int32 err)
29 {
30 // generated from:
31 // http://www.fortunecity.com/skyscraper/apple/308/html/appendd.htm
32 // with:
33 // while read N; do read V; read L; echo -e "\tcase $V: /* $N - $L */\n\t\treturn B_BAD_VALUE;"; done >> errs
34 switch (err) {
35 /* BIOS errors */
36 case 0: /* E_OK - No error */
37 return B_OK;
38 case -1: /* ERROR - Generic error */
39 return B_ERROR;
40 case -2: /* EDRVNR - Drive not ready */
41 return B_DEV_NOT_READY;
42 case -3: /* EUNCMD - Unknown command */
43 return B_BAD_VALUE; //XXX
44 case -4: /* E_CRC - CRC error */
45 return B_DEV_CRC_ERROR;
46 case -5: /* EBADRQ - Bad request */
47 return B_BAD_VALUE; //XXX
48 case -6: /* E_SEEK - Seek error */
49 return B_DEV_SEEK_ERROR;
50 case -7: /* EMEDIA - Unknown media */
51 return B_DEV_UNREADABLE;
52 case -8: /* ESECNF - Sector not found */
53 return B_DEV_FORMAT_ERROR;
54 case -9: /* EPAPER - Out of paper */
55 return B_DEVICE_NOT_FOUND;
56 case -10: /* EWRITF - Write fault */
57 return B_DEV_WRITE_ERROR;
58 case -11: /* EREADF - Read fault */
59 return B_DEV_READ_ERROR;
60 case -12: /* EWRPRO - Device is write protected */
61 return B_READ_ONLY_DEVICE;
62 case -14: /* E_CHNG - Media change detected */
63 return B_DEV_MEDIA_CHANGED;
64 case -15: /* EUNDEV - Unknown device */
65 return B_DEV_BAD_DRIVE_NUM;
66 case -16: /* EBADSF - Bad sectors on format */
67 return B_DEV_UNREADABLE;
68 case -17: /* EOTHER - Insert other disk (request) */
69 return B_DEV_MEDIA_CHANGE_REQUESTED;
70 /* GEMDOS errors */
71 case -32: /* EINVFN - Invalid function */
72 return B_BAD_VALUE;
73 case -33: /* EFILNF - File not found */
74 case -34: /* EPTHNF - Path not found */
75 return B_ENTRY_NOT_FOUND;
76 case -35: /* ENHNDL - No more handles */
77 return B_NO_MORE_FDS;
78 case -36: /* EACCDN - Access denied */
79 return B_PERMISSION_DENIED;
80 case -37: /* EIHNDL - Invalid handle */
81 return B_FILE_ERROR;
82 case -39: /* ENSMEM - Insufficient memory */
83 return B_NO_MEMORY;
84 case -40: /* EIMBA - Invalid memory block address */
85 return B_BAD_ADDRESS;
86 case -46: /* EDRIVE - Invalid drive specification */
87 return B_DEV_BAD_DRIVE_NUM;
88 case -48: /* ENSAME - Cross device rename */
89 return B_CROSS_DEVICE_LINK;
90 case -49: /* ENMFIL - No more files */
91 return B_NO_MORE_FDS;
92 case -58: /* ELOCKED - Record is already locked */
93 return B_BAD_VALUE; //XXX
94 case -59: /* ENSLOCK - Invalid lock removal request */
95 return B_BAD_VALUE; //XXX
96 case -64: /* ERANGE or ENAMETOOLONG - Range error */
97 return B_NAME_TOO_LONG;
98 case -65: /* EINTRN - Internal error */
99 return B_ERROR;
100 case -66: /* EPLFMT - Invalid program load format */
101 return B_NOT_AN_EXECUTABLE;
102 case -67: /* EGSBF - Memory block growth failure */
103 return B_BAD_VALUE;
104 case -80: /* ELOOP - Too many symbolic links */
105 return B_LINK_LIMIT;
106 case -200: /* EMOUNT - Mount point crossed (indicator) */
107 return B_BAD_VALUE;
108 default:
109 return B_ERROR;
110 }
111 }
112
113
114 /*! Maps XHDI error codes to native errors
115 * cf. http://toshyp.atari.org/010008.htm#XHDI_20error_20codes
116 */
117 extern "C" status_t
xhdierror(int32 err)118 xhdierror(int32 err)
119 {
120 if (err <= -456) {
121 int ide = -(err + 456);
122 // ide status reg
123 // guessed mapping
124 if (ide & (1 << 1)) { // track 0 not found
125 return B_DEV_FORMAT_ERROR;
126 } else if (ide & (1 << 0)) { // DAM not found
127 return B_DEV_FORMAT_ERROR;
128 } else if (ide & (1 << 4)) { // ID field not found
129 return B_DEV_ID_ERROR;
130 } else if (ide & (1 << 7)) { // bad block mark
131 return B_DEV_FORMAT_ERROR;
132 } else if (ide & (1 << 6)) { // uncorrectable error
133 return B_DEV_UNREADABLE;
134 } else if (ide & (1 << 2)) { // command aborted
135 return B_INTERRUPTED;
136 } else if (ide & (1 << 5)) { // media change
137 return B_DEV_MEDIA_CHANGED;
138 } else if (ide & (1 << 3)) { // media change requested
139 return B_DEV_MEDIA_CHANGE_REQUESTED;
140 }
141 return B_ERROR;
142 } else if (err <= -200) {
143 /* SCSI errors */
144 int scsi = -(err + 200);
145 //XXX:
146 switch (scsi) {
147 case 0x06:
148 return B_DEV_FORMAT_ERROR;
149 case 0x10:
150 return B_DEV_FORMAT_ERROR;
151 case 0x11:
152 return B_DEV_UNREADABLE;
153 case 0x12:
154 return B_DEV_ID_ERROR;
155 case 0x13:
156 return B_DEV_FORMAT_ERROR;
157 case 0x20:
158 return B_INTERRUPTED;
159 case 0x28:
160 return B_DEV_FORMAT_ERROR;
161 case 0x5a:
162 return B_DEV_FORMAT_ERROR;
163 }
164 }
165 return toserror(err);
166 }
167
168
169 static void
dump_tos_cookie(const struct tos_cookie * c)170 dump_tos_cookie(const struct tos_cookie *c)
171 {
172 if (c != NULL) {
173 dprintf("%4.4s: 0x%08lx, %ld\n", (const char *)&c->cookie, c->ivalue,
174 c->ivalue);
175 }
176 }
177
178
179 extern "C" void
dump_tos_cookies(void)180 dump_tos_cookies(void)
181 {
182 const tos_cookie *c = COOKIE_JAR;
183 dprintf("Cookies:\n");
184 while (c && (c->cookie)) {
185 dump_tos_cookie(c++);
186 }
187 }
188
189
190 extern "C" status_t
init_xhdi(void)191 init_xhdi(void)
192 {
193 const struct tos_cookie *c;
194
195 if (gXHDIEntryPoint)
196 return B_OK;
197
198 c = tos_find_cookie(XHDI_COOKIE);
199 if (!c)
200 return B_ENTRY_NOT_FOUND;
201 if (((uint32 *)c->pvalue)[-1] != XHDI_MAGIC)
202 return B_BAD_VALUE;
203 gXHDIEntryPoint = c->pvalue;
204 gXHDIVersion = XHGetVersion();
205 return B_OK;
206 }
207
208
209 extern "C" status_t
init_nat_features(void)210 init_nat_features(void)
211 {
212 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id = NULL;
213 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_call = NULL;
214 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_dprintf_id = 0;
215 if (nat_features()) {
216 // find debugprintf id
217 gDebugPrintfNatFeatID = nat_feat_getid("DEBUGPRINTF");
218 dprintf("DEBUGPRINTF natfeat id 0x%08lx\n", gDebugPrintfNatFeatID);
219 // pass native features infos to the kernel
220 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id =
221 nat_features()->nfGetID;
222 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_call =
223 nat_features()->nfCall;
224 gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_dprintf_id =
225 gDebugPrintfNatFeatID;
226 // find other natfeat ids
227 gBootstrapNatFeatID = nat_feat_getid("BOOTSTRAP");
228 dprintf("BOOTSTRAP natfeat id 0x%08lx\n", gBootstrapNatFeatID);
229 }
230 return nat_features() ? B_OK : B_ENTRY_NOT_FOUND;
231 }
232
233
234 extern "C" void
nat_feat_debugprintf(const char * str)235 nat_feat_debugprintf(const char *str)
236 {
237 if (gDebugPrintfNatFeatID)
238 nat_feat_call(gDebugPrintfNatFeatID, 0, str);
239 }
240
241 extern "C" int
nat_feat_get_bootdrive(void)242 nat_feat_get_bootdrive(void)
243 {
244 if (gBootstrapNatFeatID == 0)
245 return -1;
246 return nat_feat_call(gBootstrapNatFeatID, 1);
247 }
248
249 extern "C" status_t
nat_feat_get_bootargs(char * str,long size)250 nat_feat_get_bootargs(char *str, long size)
251 {
252 status_t err;
253 if (gBootstrapNatFeatID == 0)
254 return B_ERROR;
255 return toserror(nat_feat_call(gBootstrapNatFeatID, 2, str, size));
256 }
257