xref: /haiku/src/system/boot/platform/atari_m68k/toscalls.cpp (revision e0ef64750f3169cd634bb2f7a001e22488b05231)
1 /*
2  * Copyright 2008, 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 
23 
24 /*! Maps TOS error codes to native errors
25  */
26 extern "C" status_t
27 toserror(int32 err)
28 {
29 	// generated from:
30 	// http://www.fortunecity.com/skyscraper/apple/308/html/appendd.htm
31 	// with:
32 	// while read N; do read V; read L; echo -e "\tcase $V: /* $N - $L */\n\t\treturn EINVAL;"; done >> errs
33 	switch (err) {
34 	/* BIOS errors */
35 	case 0: /* E_OK - No error */
36 		return B_OK;
37 	case -1: /* ERROR - Generic error */
38 		return B_ERROR;
39 	case -2: /* EDRVNR - Drive not ready */
40 		return B_DEV_NOT_READY;
41 	case -3: /* EUNCMD - Unknown command */
42 		return EINVAL;	//XXX
43 	case -4: /* E_CRC - CRC error */
44 		return B_DEV_CRC_ERROR;
45 	case -5: /* EBADRQ - Bad request */
46 		return EINVAL;	//XXX
47 	case -6: /* E_SEEK - Seek error */
48 		return B_DEV_SEEK_ERROR;
49 	case -7: /* EMEDIA - Unknown media */
50 		return B_DEV_UNREADABLE;
51 	case -8: /* ESECNF - Sector not found */
52 		return B_DEV_FORMAT_ERROR;
53 	case -9: /* EPAPER - Out of paper */
54 		return ENODEV;
55 	case -10: /* EWRITF - Write fault */
56 		return B_DEV_WRITE_ERROR;
57 	case -11: /* EREADF - Read fault */
58 		return B_DEV_READ_ERROR;
59 	case -12: /* EWRPRO - Device is write protected */
60 		return B_READ_ONLY_DEVICE;
61 	case -14: /* E_CHNG - Media change detected */
62 		return B_DEV_MEDIA_CHANGED;
63 	case -15: /* EUNDEV - Unknown device */
64 		return B_DEV_BAD_DRIVE_NUM;
65 	case -16: /* EBADSF - Bad sectors on format */
66 		return B_DEV_UNREADABLE;
67 	case -17: /* EOTHER - Insert other disk (request) */
68 		return B_DEV_MEDIA_CHANGE_REQUESTED;
69 	/* GEMDOS errors */
70 	case -32: /* EINVFN - Invalid function */
71 		return EINVAL;
72 	case -33: /* EFILNF - File not found */
73 		return B_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 EACCES;
80 	case -37: /* EIHNDL - Invalid handle */
81 		return EBADF;
82 	case -39: /* ENSMEM - Insufficient memory */
83 		return ENOMEM;
84 	case -40: /* EIMBA - Invalid memory block address */
85 		return EFAULT;
86 	case -46: /* EDRIVE - Invalid drive specification */
87 		return B_DEV_BAD_DRIVE_NUM;
88 	case -48: /* ENSAME - Cross device rename */
89 		return EXDEV;
90 	case -49: /* ENMFIL - No more files */
91 		return EMFILE;
92 	case -58: /* ELOCKED - Record is already locked */
93 		return EINVAL;	//XXX
94 	case -59: /* ENSLOCK - Invalid lock removal request */
95 		return EINVAL;	//XXX
96 	case -64: /* ERANGE or ENAMETOOLONG - Range error */
97 		return ENAMETOOLONG;
98 	case -65: /* EINTRN - Internal error */
99 		return B_ERROR;
100 	case -66: /* EPLFMT - Invalid program load format */
101 		return ENOEXEC;
102 	case -67: /* EGSBF - Memory block growth failure */
103 		return EINVAL;
104 	case -80: /* ELOOP - Too many symbolic links */
105 		return ELOOP;
106 	case -200: /* EMOUNT - Mount point crossed (indicator) */
107 		return EINVAL;
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
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 EINTR;
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 EINTR;
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
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
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
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 ENOENT;
201 	if (((uint32 *)c->pvalue)[-1] != XHDI_MAGIC)
202 		return EINVAL;
203 	gXHDIEntryPoint = c->pvalue;
204 	gXHDIVersion = XHGetVersion();
205 	return B_OK;
206 }
207 
208 
209 extern "C" status_t
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 		// pass native features infos to the kernel
219 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id =
220 			nat_features()->nfGetID;
221 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_call =
222 			nat_features()->nfCall;
223 		gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_dprintf_id =
224 			gDebugPrintfNatFeatID;
225 	}
226 	return nat_features() ? B_OK : ENOENT;
227 }
228 
229 
230 extern "C" void
231 nat_feat_debugprintf(const char *str)
232 {
233 	if (gDebugPrintfNatFeatID)
234 		nat_feat_call(gDebugPrintfNatFeatID, 0, str);
235 }
236