From b516effeaab16c2b8fef351fa17ee0e429dc25d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 18 Jan 2008 01:50:36 +0000 Subject: [PATCH] Enumerating drives through XHDI seems to work, at least it seems coherent. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23598 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../boot/platform/atari_m68k/devices.cpp | 155 +++++++++++++--- .../boot/platform/atari_m68k/toscalls.c | 9 +- .../boot/platform/atari_m68k/toscalls.h | 167 +++++++++++++++++- 3 files changed, 295 insertions(+), 36 deletions(-) diff --git a/src/system/boot/platform/atari_m68k/devices.cpp b/src/system/boot/platform/atari_m68k/devices.cpp index 3511b43c59..a0a44aaf87 100644 --- a/src/system/boot/platform/atari_m68k/devices.cpp +++ b/src/system/boot/platform/atari_m68k/devices.cpp @@ -160,7 +160,7 @@ class BIOSDrive : public BlockHandle { class XHDIDrive : public BlockHandle { public: - XHDIDrive(int handle/*, uint16 major, uint16 minor ??*/); + XHDIDrive(int handle, uint16 major, uint16 minor); virtual ~XHDIDrive(); status_t FillIdentifier(); @@ -431,29 +431,112 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) if (sBlockDevicesAdded) return B_OK; - map = Drvmap(); - dprintf("Drvmap(): 0x%08lx\n", map); - for (driveID = 0; driveID < 32; driveID++) { - bool present = map & 0x1; - map >>= 1; - if (!present) - continue; - - if (driveID == gBootDriveID) - continue; + if (init_xhdi() >= B_OK) { + uint16 major; + uint16 minor; + uint32 blocksize; + uint32 blocks; + uint32 devflags; + uint32 lastacc; + char product[33]; + int32 err; - BlockHandle *drive = new(nothrow) BlockHandle(driveID); - if (drive->InitCheck() != B_OK) { - dprintf("could not add drive %u\n", driveID); - delete drive; - continue; + map = XHDrvMap(); + dprintf("XDrvMap() 0x%08lx\n", map); + // sadly XDrvmap() has the same issues as XBIOS, it only lists known partitions. + // so we just iterate on each major and try to see if there is something. + for (driveID = 0; driveID < 32; driveID++) { + uint32 startsect; + err = XHInqDev(driveID, &major, &minor, &startsect, NULL); + if (err < 0) { + ;//dprintf("XHInqDev(%d) error %d\n", driveID, err); + } else { + dprintf("XHInqDev(%d): (%d,%d):%d\n", driveID, major, minor, startsect); + } } - devicesList->Add(drive); - driveCount++; + product[32] = '\0'; + for (major = 0; major < 256; major++) { + if (major == 64) // we don't want floppies + continue; + if (major > 23) // extensions and non-standard stuff... skip for speed. + break; - if (drive->FillIdentifier() != B_OK) - identifierMissing = true; + for (minor = 0; minor < 255; minor++) { + if (minor && (major < 8 || major >15)) + break; // minor only used for the SCSI LUN AFAIK. + if (minor > 15) // are more used at all ? + break; + + product[0] = '\0'; + blocksize = 0; +#if 0 + err = XHLastAccess(major, minor, &lastacc); + if (err < 0) { + ;//dprintf("XHLastAccess(%d,%d) error %d\n", major, minor, err); + } else + dprintf("XHLastAccess(%d,%d): %ld\n", major, minor, lastacc); +//continue; +#endif + // we can pass NULL pointers but just to play safe we don't. + err = XHInqTarget(major, minor, &blocksize, &devflags, product); + if (err < 0) { + dprintf("XHInqTarget(%d,%d) error %d\n", major, minor, err); + continue; + } + err = XHGetCapacity(major, minor, &blocks, &blocksize); + if (err < 0) { + //dprintf("XHGetCapacity(%d,%d) error %d\n", major, minor, err); + continue; + } + + dprintf("XHDI(%d,%d): blksize %d, blocks %d, flags 0x%08lx, '%s'\n", major, minor, blocksize, blocks, devflags, product); + driveID = (uint8)major; + + //if (driveID == gBootDriveID) + // continue; +//continue; + + BlockHandle *drive = new(nothrow) XHDIDrive(driveID, major, minor); + if (drive->InitCheck() != B_OK) { + dprintf("could not add drive (%d,%d)\n", major, minor); + delete drive; + continue; + } + + devicesList->Add(drive); + driveCount++; + + if (drive->FillIdentifier() != B_OK) + identifierMissing = true; + } + } + } + if (!driveCount) { // try to fallback to BIOS XXX: use MetaDOS + map = Drvmap(); + dprintf("Drvmap(): 0x%08lx\n", map); + for (driveID = 0; driveID < 32; driveID++) { + bool present = map & 0x1; + map >>= 1; + if (!present) + continue; + + if (driveID == gBootDriveID) + continue; + + BlockHandle *drive = new(nothrow) BlockHandle(driveID); + if (drive->InitCheck() != B_OK) { + dprintf("could not add drive %u\n", driveID); + delete drive; + continue; + } + + devicesList->Add(drive); + driveCount++; + + if (drive->FillIdentifier() != B_OK) + identifierMissing = true; + } } dprintf("number of drives: %d\n", driveCount); @@ -690,18 +773,29 @@ BIOSDrive::ReadBlocks(void *buffer, off_t first, int32 count) */ -XHDIDrive::XHDIDrive(int handle) +XHDIDrive::XHDIDrive(int handle, uint16 major, uint16 minor) : BlockHandle(handle) { /* first check if the drive exists */ - /* note floppy B can be reported present anyway... */ - uint32 map = Drvmap(); - if (!(map & (1 << fHandle))) { - fSize = 0LL; - return; - } - //XXX: check size + int32 err; + uint32 devflags; + uint32 blocks; + char product[33]; + fMajor = major; + fMinor = minor; + product[32] = '\0'; + err = XHInqTarget(major, minor, &fBlockSize, &devflags, product); + if (err < 0) + return; + //XXX: check size + err = XHGetCapacity(major, minor, &blocks, &fBlockSize); + if (err < 0) + return; + + fSize = blocks * fBlockSize; + fHasParameters = false; +#if 0 if (get_drive_parameters(fHandle, &fParameters) != B_OK) { dprintf("getting drive parameters for: %u failed!\n", fHandle); return; @@ -709,7 +803,7 @@ XHDIDrive::XHDIDrive(int handle) fBlockSize = 512; fSize = fParameters.sectors * fBlockSize; fHasParameters = false; - +#endif #if 0 if (get_ext_drive_parameters(driveID, &fParameters) != B_OK) { // old style CHS support @@ -799,7 +893,9 @@ status_t platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) { TRACE(("boot drive ID: %x\n", gBootDriveID)); + init_xhdi(); + //XXX: FIXME BlockHandle *drive = new(nothrow) BlockHandle(gBootDriveID); if (drive->InitCheck() != B_OK) { dprintf("no boot drive!\n"); @@ -851,6 +947,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, status_t platform_add_block_devices(stage2_args *args, NodeList *devicesList) { + init_xhdi(); return add_block_devices(devicesList, false); } diff --git a/src/system/boot/platform/atari_m68k/toscalls.c b/src/system/boot/platform/atari_m68k/toscalls.c index 76261a0125..d69c143707 100644 --- a/src/system/boot/platform/atari_m68k/toscalls.c +++ b/src/system/boot/platform/atari_m68k/toscalls.c @@ -13,6 +13,8 @@ #include void *gXHDIEntryPoint = NULL; +uint32 gXHDIVersion = 0; + NatFeatCookie *gNatFeatCookie = NULL; int32 gDebugPrintfNatFeatID = 0; @@ -182,13 +184,18 @@ dump_tos_cookies(void) status_t init_xhdi(void) { - struct tos_cookie *c; + const struct tos_cookie *c; + + if (gXHDIEntryPoint) + return B_OK; + c = tos_find_cookie(XHDI_COOKIE); if (!c) return ENOENT; if (((uint32 *)c->pvalue)[-1] != XHDI_MAGIC) return EINVAL; gXHDIEntryPoint = c->pvalue; + gXHDIVersion = XHGetVersion(); return B_OK; } diff --git a/src/system/boot/platform/atari_m68k/toscalls.h b/src/system/boot/platform/atari_m68k/toscalls.h index e013f69213..59b429d61e 100644 --- a/src/system/boot/platform/atari_m68k/toscalls.h +++ b/src/system/boot/platform/atari_m68k/toscalls.h @@ -351,7 +351,8 @@ static inline int Bconputs(int16 handle, const char *string) #define XHDI_COOKIE 'XHDI' #define XHDI_MAGIC 0x27011992 -#define XHDI_CLOBBER_LIST /* only d0 */ +//#define XHDI_CLOBBER_LIST "" /* only d0 */ +#define XHDI_CLOBBER_LIST "d1", "d2", "a0", "a1", "a2" #define XH_TARGET_STOPPABLE 0x00000001L #define XH_TARGET_REMOVABLE 0x00000002L @@ -376,7 +377,7 @@ extern status_t init_xhdi(void); __asm__ volatile \ ("/* xhdicall(" #callnr ") */\n" \ " move.w %[calln],-(%%sp)\n" \ - " call (%[entry])\n" \ + " jbsr (%[entry])\n" \ " add.l #2,%%sp\n" \ : "=r"(retvalue) /* output */ \ : /* input */ \ @@ -396,7 +397,7 @@ extern status_t init_xhdi(void); ("/* xhdicall(" #callnr ") */\n" \ " move.w %1,-(%%sp) \n" \ " move.w %[calln],-(%%sp)\n" \ - " call (%[entry])\n" \ + " jbsr (%[entry])\n" \ " add.l #4,%%sp \n" \ : "=r"(retvalue) /* output */ \ : "r"(_p1), /* input */ \ @@ -407,6 +408,160 @@ extern status_t init_xhdi(void); retvalue; \ }) +#define xhdicallWWL(callnr, p1, p2, p3) \ +({ \ + register int32 retvalue __asm__("d0"); \ + int16 _p1 = (int16)(p1); \ + int16 _p2 = (int16)(p2); \ + int32 _p3 = (int32)(p3); \ + \ + __asm__ volatile \ + ("/* xhdicall(" #callnr ") */\n" \ + " move.l %3,-(%%sp) \n" \ + " move.w %2,-(%%sp) \n" \ + " move.w %1,-(%%sp) \n" \ + " move.w %[calln],-(%%sp)\n" \ + " jbsr (%[entry])\n" \ + " add.l #10,%%sp \n" \ + : "=r"(retvalue) /* output */ \ + : "r"(_p1), "r"(_p2), \ + "r"(_p3), /* input */ \ + [entry]"a"(gXHDIEntryPoint), \ + [calln]"i"(callnr) \ + : XHDI_CLOBBER_LIST /* clobbered regs */ \ + ); \ + retvalue; \ +}) + +#define xhdicallWWLL(callnr, p1, p2, p3, p4) \ +({ \ + register int32 retvalue __asm__("d0"); \ + int16 _p1 = (int16)(p1); \ + int16 _p2 = (int16)(p2); \ + int32 _p3 = (int32)(p3); \ + int32 _p4 = (int32)(p4); \ + \ + __asm__ volatile \ + ("/* xhdicall(" #callnr ") */\n" \ + " move.l %4,-(%%sp) \n" \ + " move.l %3,-(%%sp) \n" \ + " move.w %2,-(%%sp) \n" \ + " move.w %1,-(%%sp) \n" \ + " move.w %[calln],-(%%sp)\n" \ + " jbsr (%[entry])\n" \ + " add.l #14,%%sp \n" \ + : "=r"(retvalue) /* output */ \ + : "r"(_p1), "r"(_p2), \ + "r"(_p3), "r"(_p4), /* input */ \ + [entry]"a"(gXHDIEntryPoint), \ + [calln]"i"(callnr) \ + : XHDI_CLOBBER_LIST /* clobbered regs */ \ + ); \ + retvalue; \ +}) + +#define xhdicallWWLLL(callnr, p1, p2, p3, p4, p5) \ +({ \ + register int32 retvalue __asm__("d0"); \ + int16 _p1 = (int16)(p1); \ + int16 _p2 = (int16)(p2); \ + int32 _p3 = (int32)(p3); \ + int32 _p4 = (int32)(p4); \ + int32 _p5 = (int32)(p5); \ + \ + __asm__ volatile \ + ("/* xhdicall(" #callnr ") */\n" \ + " move.l %5,-(%%sp) \n" \ + " move.l %4,-(%%sp) \n" \ + " move.l %3,-(%%sp) \n" \ + " move.w %2,-(%%sp) \n" \ + " move.w %1,-(%%sp) \n" \ + " move.w %[calln],-(%%sp)\n" \ + " jbsr (%[entry])\n" \ + " add.l #18,%%sp \n" \ + : "=r"(retvalue) /* output */ \ + : "r"(_p1), "r"(_p2), \ + "r"(_p3), "r"(_p4), \ + "r"(_p5), /* input */ \ + [entry]"a"(gXHDIEntryPoint), \ + [calln]"i"(callnr) \ + : XHDI_CLOBBER_LIST /* clobbered regs */ \ + ); \ + retvalue; \ +}) + +#define xhdicallWLLLL(callnr, p1, p2, p3, p4, p5) \ +({ \ + register int32 retvalue __asm__("d0"); \ + int16 _p1 = (int16)(p1); \ + int32 _p2 = (int32)(p2); \ + int32 _p3 = (int32)(p3); \ + int32 _p4 = (int32)(p4); \ + int32 _p5 = (int32)(p5); \ + \ + __asm__ volatile \ + ("/* xhdicall(" #callnr ") */\n" \ + " move.l %5,-(%%sp) \n" \ + " move.l %4,-(%%sp) \n" \ + " move.l %3,-(%%sp) \n" \ + " move.l %2,-(%%sp) \n" \ + " move.w %1,-(%%sp) \n" \ + " move.w %[calln],-(%%sp)\n" \ + " jbsr (%[entry])\n" \ + " add.l #20,%%sp \n" \ + : "=r"(retvalue) /* output */ \ + : "r"(_p1), "r"(_p2), \ + "r"(_p3), "r"(_p4), \ + "r"(_p5), /* input */ \ + [entry]"a"(gXHDIEntryPoint), \ + [calln]"i"(callnr) \ + : XHDI_CLOBBER_LIST /* clobbered regs */ \ + ); \ + retvalue; \ +}) + +#define xhdicallWWWLWL(callnr, p1, p2, p3, p4, p5, p6) \ +({ \ + register int32 retvalue __asm__("d0"); \ + int16 _p1 = (int16)(p1); \ + int16 _p2 = (int16)(p2); \ + int16 _p3 = (int16)(p3); \ + int32 _p4 = (int32)(p4); \ + int16 _p5 = (int16)(p5); \ + int32 _p6 = (int32)(p6); \ + \ + __asm__ volatile \ + ("/* xhdicall(" #callnr ") */\n" \ + " move.l %6,-(%%sp) \n" \ + " move.w %5,-(%%sp) \n" \ + " move.l %4,-(%%sp) \n" \ + " move.w %3,-(%%sp) \n" \ + " move.w %2,-(%%sp) \n" \ + " move.w %1,-(%%sp) \n" \ + " move.w %[calln],-(%%sp)\n" \ + " jbsr (%[entry])\n" \ + " add.l #18,%%sp \n" \ + : "=r"(retvalue) /* output */ \ + : "r"(_p1), "r"(_p2), \ + "r"(_p3), "r"(_p4), \ + "r"(_p5), "r"(_p6), /* input */ \ + [entry]"a"(gXHDIEntryPoint), \ + [calln]"i"(callnr) \ + : XHDI_CLOBBER_LIST /* clobbered regs */ \ + ); \ + retvalue; \ +}) + +#define xhdicallWWP(callnr, p1, p2, p3) \ + xhdicallWWL(callnr, p1, p2, (int32)p3) +#define xhdicallWWPP(callnr, p1, p2, p3, p4) \ + xhdicallWWLL(callnr, p1, p2, (int32)p3, (int32)p4) +#define xhdicallWWPPP(callnr, p1, p2, p3, p4, p5) \ + xhdicallWWLLL(callnr, p1, p2, (int32)p3, (int32)p4, (int32)p5) +#define xhdicallWPPPP(callnr, p1, p2, p3, p4, p5) \ + xhdicallWLLLL(callnr, p1, (uint32)p2, (int32)p3, (int32)p4, (int32)p5) +#define xhdicallWWWPWP(callnr, p1, p2, p3, p4, p5, p6) \ + xhdicallWWWLWL(callnr, p1, p2, p3, (int32)p4, p5, (uint32)p6) #define XHGetVersion() (uint16)xhdicallV(0) #define XHInqTarget(major, minor, bsize, flags, pname) xhdicallWWPPP(1, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname) @@ -415,18 +570,18 @@ extern status_t init_xhdi(void); //#define XHStop() 4 #define XHEject(major, minor, doeject, key) xhdicallWWWW(5, (uint16)major, (uint16)minor, (uint16)doeject, (uint16)key) #define XHDrvMap() xhdicallV(6) -//#define XHInqDev(dev,) xhdicall(7,) +#define XHInqDev(dev,major,minor,startsect,bpb) xhdicallWPPPP(7,dev,(uint16 *)major,(uint16 *)minor,(uint32 *)startsect,(struct tos_bpb *)bpb) //XHInqDriver 8 //XHNewCookie 9 #define XHReadWrite(major, minor, rwflags, recno, count, buf) xhdicalWWWLWP(10, (uint16)major, (uint16)minor, (uint16)rwflags, (uint32)recno, (uint16)count, (void *)buf) #define XHInqTarget2(major, minor, bsize, flags, pname, pnlen) xhdicallWWPPPW(11, (uint16)major, (uint16)minor, (uint32 *)bsize, (uint32 *)flags, (char *)pname, (uint16)pnlen) //XHInqDev2 12 //XHDriverSpecial 13 -#define XHGetCapacity(major, minor, blocks, blocksize) xhdicall(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize) +#define XHGetCapacity(major, minor, blocks, blocksize) xhdicallWWPP(14, (uint16)major, (uint16)minor, (uint32 *)blocks, (uint32 *)blocksize) //#define XHMediumChanged() 15 //XHMiNTInfo 16 //XHDosLimits 17 -//XHLastAccess 18 +#define XHLastAccess(major, minor, ms) xhdicallWWP(18, major, minor, (uint32 *)ms) //SHReaccess 19 #endif /* __ASSEMBLER__ */