From 4466a74e4004a7cb50ea22e04168cbdc13838046 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Nov 2020 23:15:43 -0800 Subject: [PATCH] pf2: add diskset init --- .../libvapours/include/vapours/prfile2.hpp | 2 + .../vapours/prfile2/pdm/prfile2_pdm_api.hpp | 25 +++++++ .../prfile2/pdm/prfile2_pdm_common.hpp | 66 +++++++++++++++++++ .../vapours/prfile2/pdm/prfile2_pdm_disk.hpp | 48 ++++++++++++++ .../pdm/prfile2_pdm_disk_management.hpp | 43 ++++++++++++ .../prfile2/pdm/prfile2_pdm_partition.hpp | 52 +++++++++++++++ .../vapours/prfile2/pdm/prfile2_pdm_types.hpp | 54 +++++++++++++++ .../vapours/prfile2/prfile2_handle.hpp | 49 ++++++++++++++ .../source/prfile2/pdm/prfile2_pdm_api.cpp | 44 +++++++++++++ .../prfile2/pdm/prfile2_pdm_disk_set.hpp | 61 +++++++++++++++++ .../prfile2/prfile2_critical_section.cpp | 2 - 11 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_api.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_common.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_partition.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_types.hpp create mode 100644 libraries/libvapours/include/vapours/prfile2/prfile2_handle.hpp create mode 100644 libraries/libvapours/source/prfile2/pdm/prfile2_pdm_api.cpp create mode 100644 libraries/libvapours/source/prfile2/pdm/prfile2_pdm_disk_set.hpp diff --git a/libraries/libvapours/include/vapours/prfile2.hpp b/libraries/libvapours/include/vapours/prfile2.hpp index 708804fe3..9e712c6de 100644 --- a/libraries/libvapours/include/vapours/prfile2.hpp +++ b/libraries/libvapours/include/vapours/prfile2.hpp @@ -23,3 +23,5 @@ #include #include +#include +#include diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_api.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_api.hpp new file mode 100644 index 000000000..9ebd0c3dc --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_api.hpp @@ -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 . + */ +#pragma once +#include +#include +#include + +namespace ams::prfile2::pdm { + + pdm::Error Initialize(u32 config, void *param); + +} diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_common.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_common.hpp new file mode 100644 index 000000000..9a0b86b4a --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_common.hpp @@ -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 . + */ +#pragma once +#include +#include + +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; + }; + + /* ... */ + +} diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk.hpp new file mode 100644 index 000000000..bed18f2d9 --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk.hpp @@ -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 . + */ +#pragma once +#include +#include + +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); + + /* ... */ + + } + +} diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp new file mode 100644 index 000000000..3a9e40a7f --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_disk_management.hpp @@ -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 . + */ +#pragma once +#include +#include +#include +#include + +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]; + }; + +} diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_partition.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_partition.hpp new file mode 100644 index 000000000..49defff95 --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_partition.hpp @@ -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 . + */ +#pragma once +#include +#include + +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); + + } + +} diff --git a/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_types.hpp b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_types.hpp new file mode 100644 index 000000000..045c3e905 --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/pdm/prfile2_pdm_types.hpp @@ -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 . + */ +#pragma once +#include +#include + +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 (*)(); + +} diff --git a/libraries/libvapours/include/vapours/prfile2/prfile2_handle.hpp b/libraries/libvapours/include/vapours/prfile2/prfile2_handle.hpp new file mode 100644 index 000000000..fd92e7c58 --- /dev/null +++ b/libraries/libvapours/include/vapours/prfile2/prfile2_handle.hpp @@ -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 . + */ +#pragma once +#include + +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(id); + val.Set(kind); + val.Set(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() == HandleKind_Disk; } + constexpr ALWAYS_INLINE bool IsPartitionHandle(HandleType handle) { return handle.Get() == HandleKind_Partition; } + +} diff --git a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_api.cpp b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_api.cpp new file mode 100644 index 000000000..8c9bdae32 --- /dev/null +++ b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_api.cpp @@ -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 . + */ +#if defined(ATMOSPHERE_IS_STRATOSPHERE) +#include +#elif defined(ATMOSPHERE_IS_MESOSPHERE) +#include +#elif defined(ATMOSPHERE_IS_EXOSPHERE) +#include +#else +#include +#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; + } + +} diff --git a/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_disk_set.hpp b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_disk_set.hpp new file mode 100644 index 000000000..7c1f6eab3 --- /dev/null +++ b/libraries/libvapours/source/prfile2/pdm/prfile2_pdm_disk_set.hpp @@ -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 . + */ +#pragma once +#include + +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(); AMS_LIKELY(id < MaxDisks)) { + const auto signature = handle.Get(); + 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(); AMS_LIKELY(id < MaxPartitions)) { + const auto signature = handle.Get(); + 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; + } + +} diff --git a/libraries/libvapours/source/prfile2/prfile2_critical_section.cpp b/libraries/libvapours/source/prfile2/prfile2_critical_section.cpp index 7ee99221b..18eeb9d58 100644 --- a/libraries/libvapours/source/prfile2/prfile2_critical_section.cpp +++ b/libraries/libvapours/source/prfile2/prfile2_critical_section.cpp @@ -138,6 +138,4 @@ namespace ams::prfile2 { #endif - - }