xref: /haiku/src/system/boot/platform/atari_m68k/toscalls.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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
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 		return B_FILE_NOT_FOUND;
75 	case -34: /* EPTHNF - Path not found */
76 		return B_ENTRY_NOT_FOUND;
77 	case -35: /* ENHNDL - No more handles */
78 		return B_NO_MORE_FDS;
79 	case -36: /* EACCDN - Access denied */
80 		return B_PERMISSION_DENIED;
81 	case -37: /* EIHNDL - Invalid handle */
82 		return B_FILE_ERROR;
83 	case -39: /* ENSMEM - Insufficient memory */
84 		return B_NO_MEMORY;
85 	case -40: /* EIMBA - Invalid memory block address */
86 		return B_BAD_ADDRESS;
87 	case -46: /* EDRIVE - Invalid drive specification */
88 		return B_DEV_BAD_DRIVE_NUM;
89 	case -48: /* ENSAME - Cross device rename */
90 		return B_CROSS_DEVICE_LINK;
91 	case -49: /* ENMFIL - No more files */
92 		return B_NO_MORE_FDS;
93 	case -58: /* ELOCKED - Record is already locked */
94 		return B_BAD_VALUE;	//XXX
95 	case -59: /* ENSLOCK - Invalid lock removal request */
96 		return B_BAD_VALUE;	//XXX
97 	case -64: /* ERANGE or ENAMETOOLONG - Range error */
98 		return B_NAME_TOO_LONG;
99 	case -65: /* EINTRN - Internal error */
100 		return B_ERROR;
101 	case -66: /* EPLFMT - Invalid program load format */
102 		return B_NOT_AN_EXECUTABLE;
103 	case -67: /* EGSBF - Memory block growth failure */
104 		return B_BAD_VALUE;
105 	case -80: /* ELOOP - Too many symbolic links */
106 		return B_LINK_LIMIT;
107 	case -200: /* EMOUNT - Mount point crossed (indicator) */
108 		return B_BAD_VALUE;
109 	default:
110 		return B_ERROR;
111 	}
112 }
113 
114 
115 /*! Maps XHDI error codes to native errors
116  * cf. http://toshyp.atari.org/010008.htm#XHDI_20error_20codes
117  */
118 extern "C" status_t
119 xhdierror(int32 err)
120 {
121 	if (err <= -456) {
122 		int ide = -(err + 456);
123 		// ide status reg
124 		// guessed mapping
125 		if (ide & (1 << 1)) {	// track 0 not found
126 			return B_DEV_FORMAT_ERROR;
127 		} else if (ide & (1 << 0)) {	// DAM not found
128 			return B_DEV_FORMAT_ERROR;
129 		} else if (ide & (1 << 4)) {	// ID field not found
130 			return B_DEV_ID_ERROR;
131 		} else if (ide & (1 << 7)) {	// bad block mark
132 			return B_DEV_FORMAT_ERROR;
133 		} else if (ide & (1 << 6)) {	// uncorrectable error
134 			return B_DEV_UNREADABLE;
135 		} else if (ide & (1 << 2)) {	// command aborted
136 			return B_INTERRUPTED;
137 		} else if (ide & (1 << 5)) {	// media change
138 			return B_DEV_MEDIA_CHANGED;
139 		} else if (ide & (1 << 3)) {	// media change requested
140 			return B_DEV_MEDIA_CHANGE_REQUESTED;
141 		}
142 		return B_ERROR;
143 	} else if (err <= -200) {
144 		/* SCSI errors */
145 		int scsi = -(err + 200);
146 		//XXX:
147 		switch (scsi) {
148 		case 0x06:
149 			return B_DEV_FORMAT_ERROR;
150 		case 0x10:
151 			return B_DEV_FORMAT_ERROR;
152 		case 0x11:
153 			return B_DEV_UNREADABLE;
154 		case 0x12:
155 			return B_DEV_ID_ERROR;
156 		case 0x13:
157 			return B_DEV_FORMAT_ERROR;
158 		case 0x20:
159 			return B_INTERRUPTED;
160 		case 0x28:
161 			return B_DEV_FORMAT_ERROR;
162 		case 0x5a:
163 			return B_DEV_FORMAT_ERROR;
164 		}
165 	}
166 	return toserror(err);
167 }
168 
169 
170 static void
171 dump_tos_cookie(const struct tos_cookie *c)
172 {
173 	if (c != NULL) {
174 		dprintf("%4.4s: 0x%08lx, %ld\n", (const char *)&c->cookie, c->ivalue,
175 			c->ivalue);
176 	}
177 }
178 
179 
180 extern "C" void
181 dump_tos_cookies(void)
182 {
183 	const tos_cookie *c = COOKIE_JAR;
184 	dprintf("Cookies:\n");
185 	while (c && (c->cookie)) {
186 		dump_tos_cookie(c++);
187 	}
188 }
189 
190 
191 extern "C" status_t
192 init_xhdi(void)
193 {
194 	const struct tos_cookie *c;
195 
196 	if (gXHDIEntryPoint)
197 		return B_OK;
198 
199 	c = tos_find_cookie(XHDI_COOKIE);
200 	if (!c)
201 		return B_ENTRY_NOT_FOUND;
202 	if (((uint32 *)c->pvalue)[-1] != XHDI_MAGIC)
203 		return B_BAD_VALUE;
204 	gXHDIEntryPoint = c->pvalue;
205 	gXHDIVersion = XHGetVersion();
206 	return B_OK;
207 }
208 
209 
210 extern "C" status_t
211 init_nat_features(void)
212 {
213 	gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id = NULL;
214 	gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_call = NULL;
215 	gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_dprintf_id = 0;
216 	if (nat_features()) {
217 		// find debugprintf id
218 		gDebugPrintfNatFeatID = nat_feat_getid("DEBUGPRINTF");
219 		dprintf("DEBUGPRINTF natfeat id 0x%08lx\n", gDebugPrintfNatFeatID);
220 		// pass native features infos to the kernel
221 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id =
222 			nat_features()->nfGetID;
223 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_call =
224 			nat_features()->nfCall;
225 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_dprintf_id =
226 			gDebugPrintfNatFeatID;
227 		// find other natfeat ids
228 		gBootstrapNatFeatID = nat_feat_getid("BOOTSTRAP");
229 		dprintf("BOOTSTRAP natfeat id 0x%08lx\n", gBootstrapNatFeatID);
230 	}
231 	return nat_features() ? B_OK : B_ENTRY_NOT_FOUND;
232 }
233 
234 
235 extern "C" void
236 nat_feat_debugprintf(const char *str)
237 {
238 	if (gDebugPrintfNatFeatID)
239 		nat_feat_call(gDebugPrintfNatFeatID, 0, str);
240 }
241 
242 extern "C" int
243 nat_feat_get_bootdrive(void)
244 {
245 	if (gBootstrapNatFeatID == 0)
246 		return -1;
247 	return nat_feat_call(gBootstrapNatFeatID, 1);
248 }
249 
250 extern "C" status_t
251 nat_feat_get_bootargs(char *str, long size)
252 {
253 	status_t err;
254 	if (gBootstrapNatFeatID == 0)
255 		return B_ERROR;
256 	return toserror(nat_feat_call(gBootstrapNatFeatID, 2, str, size));
257 }
258