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 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 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 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 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 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 235 nat_feat_debugprintf(const char *str) 236 { 237 if (gDebugPrintfNatFeatID) 238 nat_feat_call(gDebugPrintfNatFeatID, 0, str); 239 } 240 241 extern "C" int 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 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