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 "Handle.h"
|
||||||
#include "toscalls.h"
|
#include "toscalls.h"
|
||||||
|
|
||||||
//#define TRACE_DEVICES
|
#define TRACE_DEVICES
|
||||||
#ifdef TRACE_DEVICES
|
#ifdef TRACE_DEVICES
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x) dprintf x
|
||||||
#else
|
#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 {
|
class BIOSDrive : public BlockHandle {
|
||||||
public:
|
public:
|
||||||
BIOSDrive(int handle);
|
BIOSDrive(int handle);
|
||||||
@ -193,7 +207,14 @@ get_drive_parameters(uint8 drive, drive_parameters *parameters)
|
|||||||
{
|
{
|
||||||
status_t err;
|
status_t err;
|
||||||
err = read_bpb(drive, ¶meters->bpb);
|
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
|
#if 0
|
||||||
// fill drive_parameters structure with useful values
|
// fill drive_parameters structure with useful values
|
||||||
parameters->parameters_size = kParametersSizeVersion1;
|
parameters->parameters_size = kParametersSizeVersion1;
|
||||||
@ -460,7 +481,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
|
|||||||
for (major = 0; major < 256; major++) {
|
for (major = 0; major < 256; major++) {
|
||||||
if (major == 64) // we don't want floppies
|
if (major == 64) // we don't want floppies
|
||||||
continue;
|
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;
|
break;
|
||||||
|
|
||||||
for (minor = 0; minor < 255; minor++) {
|
for (minor = 0; minor < 255; minor++) {
|
||||||
@ -563,6 +584,10 @@ add_block_devices(NodeList *devicesList, bool identifierMissing)
|
|||||||
|
|
||||||
BlockHandle::BlockHandle(int handle)
|
BlockHandle::BlockHandle(int handle)
|
||||||
: Handle(handle)
|
: Handle(handle)
|
||||||
|
, fSize(0LL)
|
||||||
|
, fBlockSize(0)
|
||||||
|
, fHasParameters(false)
|
||||||
|
|
||||||
{
|
{
|
||||||
TRACE(("BlockHandle::%s(): drive ID %u\n", __FUNCTION__, fHandle));
|
TRACE(("BlockHandle::%s(): drive ID %u\n", __FUNCTION__, fHandle));
|
||||||
}
|
}
|
||||||
@ -648,6 +673,158 @@ BlockHandle::FillIdentifier()
|
|||||||
return B_NOT_ALLOWED;
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -928,7 +1105,16 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
|
|||||||
init_xhdi();
|
init_xhdi();
|
||||||
|
|
||||||
//XXX: FIXME
|
//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) {
|
if (drive->InitCheck() != B_OK) {
|
||||||
dprintf("no boot drive!\n");
|
dprintf("no boot drive!\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
@ -134,11 +134,46 @@ extern "C" {
|
|||||||
retvalue; \
|
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 */
|
/* pointer versions */
|
||||||
#define toscallP(trapnr, callnr, a) toscallL(trapnr, callnr, (int32)a)
|
#define toscallP(trapnr, callnr, a) toscallL(trapnr, callnr, (int32)a)
|
||||||
#define toscallWPWWWL(trapnr, callnr, p1, p2, p3, p4, p5, p6) \
|
#define toscallWPWWWL(trapnr, callnr, p1, p2, p3, p4, p5, p6) \
|
||||||
toscallWLWWWL(trapnr, callnr, p1, (int32)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 Getrez() toscallV(XBIOS_TRAP, 4)
|
||||||
#define Setscreen(log, phys, mode) toscallPPW(XBIOS_TRAP, 5, (void *)log, (void *)phys, (int16)mode)
|
#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 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 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 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)
|
//#define Keytbl(unshift, shift, caps) (KEYTAB *)toscallPPP(XBIOS_TRAP, 16, (char *)unshift, (char *)shift, (char *)caps)
|
||||||
|
Loading…
Reference in New Issue
Block a user