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