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