Implemented a FloppyDrive class that uses Floprd, this allows the loader to start reading the tgz, but it fails after 2 blocks.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30464 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2009-04-27 16:18:08 +00:00
parent cad2c3d0a5
commit f77b0a6b83
2 changed files with 227 additions and 5 deletions

View File

@ -15,7 +15,7 @@
#include "Handle.h"
#include "toscalls.h"
//#define TRACE_DEVICES
#define TRACE_DEVICES
#ifdef TRACE_DEVICES
# define TRACE(x) dprintf x
#else
@ -144,6 +144,20 @@ class BlockHandle : public Handle {
};
class FloppyDrive : public BlockHandle {
public:
FloppyDrive(int handle);
virtual ~FloppyDrive();
status_t FillIdentifier();
virtual ssize_t ReadBlocks(void *buffer, off_t first, int32 count);
protected:
status_t ReadBPB(struct tos_bpb *bpb);
};
class BIOSDrive : public BlockHandle {
public:
BIOSDrive(int handle);
@ -193,7 +207,14 @@ get_drive_parameters(uint8 drive, drive_parameters *parameters)
{
status_t err;
err = read_bpb(drive, &parameters->bpb);
TRACE(("get_drive_parameters: get_bpb: 0x%08lx\n", err));
TRACE(("get_drive_parameters: bpb: %04x %04x %04x %04x %04x %04x %04x %04x %04x \n",
parameters->bpb.recsiz, parameters->bpb.clsiz,
parameters->bpb.clsizb, parameters->bpb.rdlen,
parameters->bpb.fsiz, parameters->bpb.fatrec,
parameters->bpb.datrec, parameters->bpb.numcl,
parameters->bpb.bflags));
#if 0
// fill drive_parameters structure with useful values
parameters->parameters_size = kParametersSizeVersion1;
@ -460,7 +481,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
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.
if (major > 23 && major != 64) // extensions and non-standard stuff... skip for speed.
break;
for (minor = 0; minor < 255; minor++) {
@ -563,6 +584,10 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
BlockHandle::BlockHandle(int handle)
: Handle(handle)
, fSize(0LL)
, fBlockSize(0)
, fHasParameters(false)
{
TRACE(("BlockHandle::%s(): drive ID %u\n", __FUNCTION__, fHandle));
}
@ -648,6 +673,158 @@ BlockHandle::FillIdentifier()
return B_NOT_ALLOWED;
}
// #pragma mark -
/*
* BIOS based disk access.
* Only for fallback from missing XHDI.
* XXX: This is broken!
* XXX: check for physical drives in PUN_INFO
* XXX: at least try to use MetaDOS calls instead.
*/
FloppyDrive::FloppyDrive(int handle)
: BlockHandle(handle)
{
TRACE(("FloppyDrive::%s(%d)\n", __FUNCTION__, fHandle));
/* 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
if (get_drive_parameters(fHandle, &fParameters) != B_OK) {
dprintf("getting drive parameters for: %u failed!\n", fHandle);
return;
}
fBlockSize = 512;
fParameters.sectors = 1440 * 1024 / 512;
fSize = fParameters.sectors * fBlockSize;
fHasParameters = false;
/*
parameters->sectors_per_track = 9;
parameters->cylinders = (1440/2) / (9*2);
parameters->heads = 2;
parameters->sectors = parameters->cylinders * parameters->heads
* parameters->sectors_per_track;
*/
#if 0
if (get_ext_drive_parameters(driveID, &fParameters) != B_OK) {
// old style CHS support
if (get_drive_parameters(driveID, &fParameters) != B_OK) {
dprintf("getting drive parameters for: %u failed!\n", fDriveID);
return;
}
TRACE((" cylinders: %lu, heads: %lu, sectors: %lu, bytes_per_sector: %u\n",
fParameters.cylinders, fParameters.heads, fParameters.sectors_per_track,
fParameters.bytes_per_sector));
TRACE((" total sectors: %Ld\n", fParameters.sectors));
fBlockSize = 512;
fSize = fParameters.sectors * fBlockSize;
fLBA = false;
fHasParameters = false;
} else {
TRACE(("size: %x\n", fParameters.parameters_size));
TRACE(("drive_path_signature: %x\n", fParameters.device_path_signature));
TRACE(("host bus: \"%s\", interface: \"%s\"\n", fParameters.host_bus,
fParameters.interface_type));
TRACE(("cylinders: %lu, heads: %lu, sectors: %lu, bytes_per_sector: %u\n",
fParameters.cylinders, fParameters.heads, fParameters.sectors_per_track,
fParameters.bytes_per_sector));
TRACE(("total sectors: %Ld\n", fParameters.sectors));
fBlockSize = fParameters.bytes_per_sector;
fSize = fParameters.sectors * fBlockSize;
fLBA = true;
fHasParameters = true;
}
#endif
}
FloppyDrive::~FloppyDrive()
{
}
status_t
FloppyDrive::FillIdentifier()
{
TRACE(("FloppyDrive::%s: (%d)\n", __FUNCTION__, fHandle));
#if 0
if (HasParameters()) {
// try all drive_parameters versions, beginning from the most informative
#if 0
if (fill_disk_identifier_v3(fIdentifier, fParameters) == B_OK)
return B_OK;
if (fill_disk_identifier_v2(fIdentifier, fParameters) == B_OK)
return B_OK;
#else
// TODO: the above version is the correct one - it's currently
// disabled, as the kernel boot code only supports the
// UNKNOWN_BUS/UNKNOWN_DEVICE way to find the correct boot
// device.
if (fill_disk_identifier_v3(fIdentifier, fParameters) != B_OK)
fill_disk_identifier_v2(fIdentifier, fParameters);
#endif
// no interesting information, we have to fall back to the default
// unknown interface/device type identifier
}
fIdentifier.bus_type = UNKNOWN_BUS;
fIdentifier.device_type = UNKNOWN_DEVICE;
fIdentifier.device.unknown.size = Size();
for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) {
fIdentifier.device.unknown.check_sums[i].offset = -1;
fIdentifier.device.unknown.check_sums[i].sum = 0;
}
#endif
return B_ERROR;
}
ssize_t
FloppyDrive::ReadBlocks(void *buffer, off_t first, int32 count)
{
int sectorsPerBlocks = (fBlockSize / 512);
int32 ret;
TRACE(("FloppyDrive::%s(%Ld,%ld) (%d)\n", __FUNCTION__, first, count, fHandle));
// force single sector reads to avoid crossing track boundaries
for (int i = 0; i < count; i++) {
uint8 *buf = (uint8 *)buffer;
buf += i * fBlockSize;
int16 track, side, sect;
sect = (first + i) * sectorsPerBlocks;
track = sect / (9 * 2);
side = (sect / 9) % 2;
sect %= 9;
sect++; // 1-based
TRACE(("FloppyDrive::%s: THS: %d %d %d\n", __FUNCTION__, track, side, sect));
ret = Floprd(buf, 0L, fHandle, sect, track, side, 1);
if (ret < 0)
return toserror(ret);
}
return count;
}
// #pragma mark -
/*
@ -928,7 +1105,16 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
init_xhdi();
//XXX: FIXME
BlockHandle *drive = new(nothrow) BlockHandle(gBootDriveID);
//BlockHandle *drive = new(nothrow) BlockHandle(gBootDriveID);
BlockHandle *drive;
switch (gBootDriveID) {
case 0:
case 1:
drive = new(nothrow) FloppyDrive(gBootDriveID);
break;
default:
drive = new(nothrow) BIOSDrive(gBootDriveID);
}
if (drive->InitCheck() != B_OK) {
dprintf("no boot drive!\n");
return B_ERROR;

View File

@ -134,11 +134,46 @@ extern "C" {
retvalue; \
})
#define toscallLLWWWWW(trapnr, callnr, p1, p2, p3, p4, p5, p6, p7) \
({ \
register int32 retvalue __asm__("d0"); \
int32 _p1 = (int32)(p1); \
int32 _p2 = (int32)(p2); \
int16 _p3 = (int16)(p3); \
int16 _p4 = (int16)(p4); \
int16 _p5 = (int16)(p5); \
int16 _p6 = (int16)(p6); \
int16 _p7 = (int16)(p7); \
\
__asm__ volatile \
(/*"; toscall(" #trapnr ", " #callnr ")"*/"\n \
move.w %7,-(%%sp) \n \
move.w %6,-(%%sp) \n \
move.w %5,-(%%sp) \n \
move.w %4,-(%%sp) \n \
move.w %3,-(%%sp) \n \
move.l %2,-(%%sp) \n \
move.l %1,-(%%sp) \n \
move.w %[calln],-(%%sp)\n \
trap %[trapn]\n \
add.l #18,%%sp \n " \
: "=r"(retvalue) /* output */ \
: "r"(_p1), "r"(_p2), \
"r"(_p3), "r"(_p4), \
"r"(_p5), "r"(_p6), \
"r"(_p7), /* input */ \
[trapn]"i"(trapnr),[calln]"i"(callnr) \
: TOS_CLOBBER_LIST /* clobbered regs */ \
); \
retvalue; \
})
/* pointer versions */
#define toscallP(trapnr, callnr, a) toscallL(trapnr, callnr, (int32)a)
#define toscallWPWWWL(trapnr, callnr, p1, p2, p3, p4, p5, p6) \
toscallWLWWWL(trapnr, callnr, p1, (int32)p2, p3, p4, p5, p6)
#define toscallPLWWWWW(trapnr, callnr, p1, p2, p3, p4, p5, p6, p7) \
toscallLLWWWWW(trapnr, callnr, (int32)p1, (int32)p2, p3, p4, p5, p6, p7)
@ -323,6 +358,7 @@ static inline int Bconputs(int16 handle, const char *string)
//#define Getrez() toscallV(XBIOS_TRAP, 4)
#define Setscreen(log, phys, mode) toscallPPW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode)
#define VsetScreen(log, phys, mode, modecode) toscallPPW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode)
#define Floprd(buf, dummy, dev, sect, track, side, count) toscallPLWWWWW(XBIOS_TRAP, 8, (void *)buf, (int32)dummy, (int16)dev, (int16)sect, (int16)track, (int16)side, (int16)count)
//#define Mfpint() toscallV(XBIOS_TRAP, 13, )
#define Rsconf(speed, flow, ucr, rsr, tsr, scr) toscallWWWWWW(XBIOS_TRAP, 15, (int16)speed, (int16)flow, (int16)ucr, (int16)rsr, (int16)tsr, (int16)scr)
//#define Keytbl(unshift, shift, caps) (KEYTAB *)toscallPPP(XBIOS_TRAP, 16, (char *)unshift, (char *)shift, (char *)caps)