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:
parent
cad2c3d0a5
commit
f77b0a6b83
@ -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, ¶meters->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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user