pf2: add diskset init

This commit is contained in:
Michael Scire 2020-11-25 23:15:43 -08:00
parent dd6c9e1de1
commit 4466a74e40
11 changed files with 444 additions and 2 deletions

View file

@ -23,3 +23,5 @@
#include <vapours/prfile2/prfile2_common.hpp> #include <vapours/prfile2/prfile2_common.hpp>
#include <vapours/prfile2/prfile2_system.hpp> #include <vapours/prfile2/prfile2_system.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_api.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp>

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/pdm/prfile2_pdm_types.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_common.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp>
namespace ams::prfile2::pdm {
pdm::Error Initialize(u32 config, void *param);
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_build_config.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_types.hpp>
namespace ams::prfile2::pdm {
constexpr inline const auto MaxDisks = 5;
constexpr inline const auto MaxPartitions = 5;
struct Disk;
struct Partition;
using PartitionEventCallback = void (*)(u32 event, void *param);
using EraseFunction = pdm::Error (*)(u32, u32);
struct DiskInfo {
u32 total_sectors;
u16 cylinders;
u8 heads;
u8 sectors_per_track;
u16 bytes_per_sector;
u32 media_attr;
void *format_param;
/* ... */
};
struct FunctionTable {
pdm::Error (*initialize)(Disk *);
pdm::Error (*finalize)(Disk *);
pdm::Error (*mount)(Disk *);
pdm::Error (*unmount)(Disk *);
pdm::Error (*format)(Disk *, const u8 *);
pdm::Error (*physical_read)(Disk *disk, u8 *dst, u32 block, u32 count, u32 *num_read);
pdm::Error (*physical_write)(Disk *disk, const u8 *src, u32 block, u32 count, u32 *num_read);
pdm::Error (*get_disk_info)(Disk *disk, DiskInfo *out);
};
struct DiskTable {
FunctionTable *function_table;
u64 ui_ext;
};
struct InitDisk {
pdm::Error (*function)(DiskTable *disk_table, u64 ui_ext);
u64 ui_ext;
};
/* ... */
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_handle.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_common.hpp>
namespace ams::prfile2::pdm {
struct Disk {
u32 status;
DiskTable disk_table;
u32 signature;
u16 open_count;
u16 lock_count;
Disk *lock_handle;
DiskInfo disk_info;
InitDisk *init_disk_table;
Partition *current_partition;
DiskCallback erase_callback;
bool is_inserted;
volatile NonBlockingProtocolType nbc;
volatile NonBlockingProtocolType nbc_detect;
volatile NonBlockingProtocolType nbc_req;
};
namespace disk {
pdm::Error OpenDisk(InitDisk *init_disk_table, Disk **out);
pdm::Error CloseDisk(Disk *disk);
/* ... */
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_handle.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_common.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_disk.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_partition.hpp>
namespace ams::prfile2::pdm {
struct PartitionHolder {
u32 signature;
Partition *partition;
};
struct DiskHolder {
u32 signature;
Disk *disk;
};
struct DiskSet {
u16 num_partitions;
u16 num_allocated_disks;
DiskHolder disk_holders[MaxDisks];
PartitionHolder partition_holders[MaxPartitions];
Disk disks[MaxDisks];
Partition partitions[MaxPartitions];
};
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_handle.hpp>
#include <vapours/prfile2/pdm/prfile2_pdm_common.hpp>
namespace ams::prfile2::pdm {
struct Partition {
u32 status;
Disk *disk;
u32 signature;
u16 partition_id;
u16 open_count;
Partition *lock_handle;
u32 start_sector;
u32 total_sector;
u32 mbr_sector;
u8 partition_type;
pdm::Error last_driver_error;
void *volume;
volatile NonBlockingProtocolType nbc_detect;
PartitionEventCallback event_callback;
void *event_callback_param;
};
namespace part {
pdm::Error OpenPartition(Disk *disk, u16 partition_id, Partition **out);
pdm::Error ClosePartition(Partition *part);
void SetDriverErrorCode(Partition *part, pdm::Error err);
void CheckPartitionOpen(Disk *disk, bool *out);
void NotifyMediaEvent(Disk *disk, u32 event);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_build_config.hpp>
#include <vapours/prfile2/prfile2_handle.hpp>
namespace ams::prfile2::pdm {
enum Error {
Error_NoError = 0,
Error_Ok = Error_NoError,
Error_InvalidParameter = 0x0001,
Error_InvalidMasterBoot = 0x0002,
Error_InvalidBootSector = 0x0003,
Error_InvalidBpb = 0x0004,
Error_NotExistMbr = 0x0005,
Error_NotExistEpbr = 0x0006,
Error_NotExistPartition = 0x0007,
Error_NotExistFreeDiskStruct = 0x0008,
Error_NotExistPartitionStruct = 0x0009,
Error_NotExistFreePartitionStruct = 0x000A,
Error_StateOpened = 0x000B,
Error_StateClosed = 0x000C,
Error_StateLocked = 0x000D,
Error_StateUnlocked = 0x000E,
Error_AccessPermission = 0x000F,
Error_WriteProtected = 0x0010,
Error_MediaEjected = 0x0011,
Error_OutOfRange = 0x0012,
Error_SystemCallError = 0x0013,
Error_LockError = 0x0014,
Error_DriverError = 0x0015,
Error_UnsupportDiskFormat = 0x0016,
};
using NonBlockingProtocolType = int;
using DiskCallback = void (*)();
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours/prfile2/prfile2_common.hpp>
namespace ams::prfile2 {
using HandleType = util::BitPack32;
struct HandleField {
using Id = util::BitPack32::Field< 0, 8>;
using Kind = util::BitPack32::Field< 8, 8>;
using Signature = util::BitPack32::Field<16, 16>;
};
enum HandleKind {
HandleKind_Disk = 3,
HandleKind_Partition = 4,
};
constexpr ALWAYS_INLINE HandleType ConstructHandle(u8 id, HandleKind kind, u16 signature) {
/* Construct the handle. */
HandleType val = {};
val.Set<HandleField::Id>(id);
val.Set<HandleField::Kind>(kind);
val.Set<HandleField::Signature>(signature);
return val;
};
constexpr ALWAYS_INLINE HandleType ConstructDiskHandle(u8 id, u16 signature) { return ConstructHandle(id, HandleKind_Disk, signature); }
constexpr ALWAYS_INLINE HandleType ConstructPartitionHandle(u8 id, u16 signature) { return ConstructHandle(id, HandleKind_Partition, signature); }
constexpr ALWAYS_INLINE bool IsDiskHandle(HandleType handle) { return handle.Get<HandleField::Kind>() == HandleKind_Disk; }
constexpr ALWAYS_INLINE bool IsPartitionHandle(HandleType handle) { return handle.Get<HandleField::Kind>() == HandleKind_Partition; }
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(ATMOSPHERE_IS_STRATOSPHERE)
#include <stratosphere.hpp>
#elif defined(ATMOSPHERE_IS_MESOSPHERE)
#include <mesosphere.hpp>
#elif defined(ATMOSPHERE_IS_EXOSPHERE)
#include <exosphere.hpp>
#else
#include <vapours.hpp>
#endif
#include "prfile2_pdm_disk_set.hpp"
namespace ams::prfile2::pdm {
namespace impl {
constinit DiskSet g_disk_set;
}
pdm::Error Initialize(u32 config, void *param) {
AMS_UNUSED(config, param);
/* Clear the disk set. */
std::memset(std::addressof(impl::g_disk_set), 0, sizeof(impl::g_disk_set));
return pdm::Error_Ok;
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::prfile2::pdm {
namespace impl {
extern DiskSet g_disk_set;
}
ALWAYS_INLINE Disk *GetDisk(HandleType handle) {
if (AMS_LIKELY(IsDiskHandle(handle))) {
if (const auto id = handle.Get<HandleField::Id>(); AMS_LIKELY(id < MaxDisks)) {
const auto signature = handle.Get<HandleField::Signature>();
Disk *disk = std::addressof(impl::g_disk_set.disks[id]);
for (const auto &holder : impl::g_disk_set.disk_holders) {
if (holder.disk == disk && holder.signature == signature) {
return disk;
}
}
}
}
return nullptr;
}
ALWAYS_INLINE Partition *GetPartition(HandleType handle) {
if (AMS_LIKELY(IsPartitionHandle(handle))) {
if (const auto id = handle.Get<HandleField::Id>(); AMS_LIKELY(id < MaxPartitions)) {
const auto signature = handle.Get<HandleField::Signature>();
Partition *part = std::addressof(impl::g_disk_set.partitions[id]);
for (const auto &holder : impl::g_disk_set.partition_holders) {
if (holder.partition == part && holder.signature == signature) {
return part;
}
}
}
}
return nullptr;
}
}

View file

@ -138,6 +138,4 @@ namespace ams::prfile2 {
#endif #endif
} }