mirror of
https://github.com/StrikerX3/StrikeBox.git
synced 2024-06-23 14:53:22 -04:00
Respond to a few ATAPI commands in the early initialization procedure
Still getting stuck waiting for a DMA read
This commit is contained in:
parent
d913d6695f
commit
3acc9559a3
|
@ -161,10 +161,10 @@ enum PageControl : uint8_t {
|
|||
|
||||
// Operation Codes
|
||||
enum Operations : uint8_t {
|
||||
OpModeSense10 = 0x5A, // MODE SENSE (10 bytes)
|
||||
OpReadCapacity = 0x25, // READ CAPACITY
|
||||
OpRequestSense = 0x03, // REQUEST SENSE
|
||||
OpTestUnitReady = 0x00, // TEST UNIT READY
|
||||
OpModeSense10 = 0x5A, // (0x5A) MODE SENSE (10 bytes)
|
||||
OpReadCapacity = 0x25, // (0x25) READ CAPACITY
|
||||
OpRequestSense = 0x03, // (0x03) REQUEST SENSE
|
||||
OpTestUnitReady = 0x00, // (0x00) TEST UNIT READY
|
||||
};
|
||||
|
||||
// ----- Operation data -------------------------------------------------------
|
||||
|
|
|
@ -17,7 +17,7 @@ inline uint16_t B2L16(uint8_t bytes[2]) {
|
|||
|
||||
// Converts a 24-bit unsigned integer from big-endian to little-endian.
|
||||
inline uint32_t B2L24(uint8_t high, uint8_t low[2]) {
|
||||
return (high << 24) | B2L16(low);
|
||||
return (high << 16) | B2L16(low);
|
||||
}
|
||||
|
||||
// Converts a 32-bit unsigned integer from big-endian to little-endian.
|
||||
|
@ -31,6 +31,40 @@ inline uint64_t B2L64(uint8_t bytes[8]) {
|
|||
| ((uint64_t)bytes[4] << 24L) | ((uint64_t)bytes[5] << 16L) | ((uint64_t)bytes[6] << 8L) | (uint64_t)bytes[7];
|
||||
}
|
||||
|
||||
|
||||
// Converts a 16-bit unsigned integer from little-endian to big-endian.
|
||||
inline void L2B16(uint8_t bytes[2], uint16_t val) {
|
||||
bytes[0] = val >> 8;
|
||||
bytes[1] = val;
|
||||
}
|
||||
|
||||
// Converts a 24-bit unsigned integer from little-endian to big-endian.
|
||||
inline void L2B24(uint8_t *high, uint8_t low[2], uint32_t val) {
|
||||
*high = val >> 16;
|
||||
low[0] = val >> 8;
|
||||
low[1] = val;
|
||||
}
|
||||
|
||||
// Converts a 32-bit unsigned integer from little-endian to big-endian.
|
||||
inline void L2B32(uint8_t bytes[4], uint32_t val) {
|
||||
bytes[0] = val >> 24;
|
||||
bytes[1] = val >> 16;
|
||||
bytes[2] = val >> 8;
|
||||
bytes[3] = val;
|
||||
}
|
||||
|
||||
// Converts a 64-bit unsigned integer from little-endian to big-endian.
|
||||
inline void L2B64(uint8_t bytes[8], uint64_t val) {
|
||||
bytes[0] = val >> 56L;
|
||||
bytes[1] = val >> 48L;
|
||||
bytes[2] = val >> 40L;
|
||||
bytes[3] = val >> 32L;
|
||||
bytes[4] = val >> 24L;
|
||||
bytes[5] = val >> 16L;
|
||||
bytes[6] = val >> 8L;
|
||||
bytes[7] = val;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,10 +134,10 @@ bool BaseDVDDriveATADeviceDriver::ValidateCommand(PacketInformation& packetInfo)
|
|||
// TODO: is it correct to fail if the length is smaller than the page data?
|
||||
if (B2L16(packetInfo.cdb.modeSense10.length) < sizeof(XboxDVDAuthentication)) {
|
||||
packetInfo.result.aborted = true;
|
||||
packetInfo.result.incorrectLength = true;
|
||||
packetInfo.result.status = StCheckCondition;
|
||||
packetInfo.result.senseKey = SKIllegalRequest;
|
||||
packetInfo.result.additionalSenseCode = ASCInvalidFieldInCDB;
|
||||
packetInfo.result.incorrectLength = true;
|
||||
return false;
|
||||
}
|
||||
packetInfo.transferSize = sizeof(XboxDVDAuthentication);
|
||||
|
@ -147,6 +147,9 @@ bool BaseDVDDriveATADeviceDriver::ValidateCommand(PacketInformation& packetInfo)
|
|||
case OpRequestSense:
|
||||
packetInfo.transferSize = packetInfo.cdb.requestSense.length;
|
||||
return true;
|
||||
case OpReadCapacity:
|
||||
packetInfo.transferSize = sizeof(ReadCapacityData);
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -14,11 +14,15 @@
|
|||
#include "vixen/log.h"
|
||||
#include "vixen/io.h"
|
||||
#include "vixen/hw/ata/atapi_defs.h"
|
||||
#include "vixen/hw/ata/atapi_xbox.h"
|
||||
#include "vixen/hw/ata/atapi_utils.h"
|
||||
|
||||
namespace vixen {
|
||||
namespace hw {
|
||||
namespace ata {
|
||||
|
||||
using namespace atapi;
|
||||
|
||||
DummyDVDDriveATADeviceDriver::DummyDVDDriveATADeviceDriver() {
|
||||
strcpy(m_serialNumber, "1234567890");
|
||||
strcpy(m_firmwareRevision, "1.00");
|
||||
|
@ -41,8 +45,8 @@ bool DummyDVDDriveATADeviceDriver::Write(uint64_t byteAddress, uint8_t *buffer,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DummyDVDDriveATADeviceDriver::ValidateATAPIPacket(atapi::PacketInformation& packetInfo) {
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ValidateATAPIPacket: Operation Code 0x%x -> Command Code 0x%x Group Code 0x%x\n", packetInfo.cdb.opCode.u8, packetInfo.cdb.opCode.fields.commandCode, packetInfo.cdb.opCode.fields.groupCode);
|
||||
bool DummyDVDDriveATADeviceDriver::ValidateATAPIPacket(PacketInformation& packetInfo) {
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ValidateATAPIPacket: Operation code 0x%x\n", packetInfo.cdb.opCode.u8, packetInfo.cdb.opCode.fields.commandCode, packetInfo.cdb.opCode.fields.groupCode);
|
||||
|
||||
// TODO: device-specific validation
|
||||
|
||||
|
@ -50,24 +54,71 @@ bool DummyDVDDriveATADeviceDriver::ValidateATAPIPacket(atapi::PacketInformation&
|
|||
return ValidateCommand(packetInfo);
|
||||
}
|
||||
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketNonData(atapi::PacketInformation& packetInfo) {
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketNonData: Operation Code 0x%x -> Command Code 0x%x Group Code 0x%x\n", packetInfo.cdb.opCode.u8, packetInfo.cdb.opCode.fields.commandCode, packetInfo.cdb.opCode.fields.groupCode);
|
||||
|
||||
// TODO: implement
|
||||
return false;
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketNonData(PacketInformation& packetInfo) {
|
||||
switch (packetInfo.cdb.opCode.u8) {
|
||||
case OpTestUnitReady:
|
||||
// Say that there is no disc in the drive
|
||||
packetInfo.result.status = StCheckCondition;
|
||||
packetInfo.result.senseKey = SKNotReady;
|
||||
packetInfo.result.additionalSenseCode = ASCMediumNotPresent;
|
||||
return true;
|
||||
default:
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketNonData: Unimplemented operation code 0x%x\n", packetInfo.cdb.opCode.u8);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead(atapi::PacketInformation& packetInfo, uint8_t *packetDataBuffer, uint16_t byteCountLimit, uint32_t *packetDataSize) {
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead: Operation Code 0x%x -> Command Code 0x%x Group Code 0x%x byte count limit = 0x%x\n", packetInfo.cdb.opCode.u8, packetInfo.cdb.opCode.fields.commandCode, packetInfo.cdb.opCode.fields.groupCode, byteCountLimit);
|
||||
|
||||
// TODO: implement
|
||||
return false;
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead(PacketInformation& packetInfo, uint8_t *packetDataBuffer, uint16_t byteCountLimit, uint32_t *packetDataSize) {
|
||||
switch (packetInfo.cdb.opCode.u8) {
|
||||
case OpModeSense10:
|
||||
switch (packetInfo.cdb.modeSense10.pageCode) {
|
||||
case kPageCodeAuthentication:
|
||||
{
|
||||
// TODO: handle partial reads
|
||||
if (byteCountLimit < sizeof(XboxDVDAuthentication)) {
|
||||
packetInfo.result.aborted = true;
|
||||
packetInfo.result.deviceFault = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill in just enough information to pass basic authentication checks on modified kernels
|
||||
// TODO: Research Xbox DVD authentication
|
||||
// https://multimedia.cx/eggs/xbox-sphinx-protocol/
|
||||
XboxDVDAuthentication *dvdAuth = reinterpret_cast<XboxDVDAuthentication *>(packetDataBuffer);
|
||||
dvdAuth->CDFValid = 1;
|
||||
dvdAuth->PartitionArea = 1;
|
||||
dvdAuth->Authentication = 1;
|
||||
|
||||
*packetDataSize = sizeof(XboxDVDAuthentication);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead: Unimplemented page code 0x%x for MODE SENSE(10)\n", packetInfo.cdb.modeSense10.pageCode);
|
||||
return false;
|
||||
}
|
||||
case OpReadCapacity:
|
||||
{
|
||||
// Say that there is no disc in the drive
|
||||
packetInfo.result.status = StCheckCondition;
|
||||
packetInfo.result.senseKey = SKNotReady;
|
||||
packetInfo.result.additionalSenseCode = ASCMediumNotPresent;
|
||||
|
||||
ReadCapacityData *capData = reinterpret_cast<ReadCapacityData *>(packetDataBuffer);
|
||||
L2B32(capData->lba, 0);
|
||||
L2B32(capData->blockLength, 0);
|
||||
|
||||
*packetDataSize = sizeof(ReadCapacityData);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataRead: Unimplemented operation code 0x%x\n", packetInfo.cdb.opCode.u8);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataWrite(atapi::PacketInformation& packetInfo, uint8_t *packetDataBuffer, uint16_t byteCountLimit) {
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataWrite: Operation Code 0x%x -> Command Code 0x%x Group Code 0x%x byte count limit = 0x%x\n", packetInfo.cdb.opCode.u8, packetInfo.cdb.opCode.fields.commandCode, packetInfo.cdb.opCode.fields.groupCode, byteCountLimit);
|
||||
bool DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataWrite(PacketInformation& packetInfo, uint8_t *packetDataBuffer, uint16_t byteCountLimit) {
|
||||
|
||||
// TODO: implement
|
||||
log_debug("DummyDVDDriveATADeviceDriver::ProcessATAPIPacketDataWrite: Unimplemented operation code 0x%x\n", packetInfo.cdb.opCode.u8);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue