Commit graph

86 commits

Author SHA1 Message Date
Liav A 1f9d3a3523 Kernel/PCI: Hold a reference to DeviceIdentifier in the Device class
There are now 2 separate classes for almost the same object type:
- EnumerableDeviceIdentifier, which is used in the enumeration code for
  all PCI host controller classes. This is allowed to be moved and
  copied, as it doesn't support ref-counting.
- DeviceIdentifier, which inherits from EnumerableDeviceIdentifier. This
  class uses ref-counting, and is not allowed to be copied. It has a
  spinlock member in its structure to allow safely executing complicated
  IO sequences on a PCI device and its space configuration.
  There's a static method that allows a quick conversion from
  EnumerableDeviceIdentifier to DeviceIdentifier while creating a
  NonnullRefPtr out of it.

The reason for doing this is for the sake of integrity and reliablity of
the system in 2 places:
- Ensure that "complicated" tasks that rely on manipulating PCI device
  registers are done in a safe manner. For example, determining a PCI
  BAR space size requires multiple read and writes to the same register,
  and if another CPU tries to do something else with our selected
  register, then the result will be a catastrophe.
- Allow the PCI API to have a united form around a shared object which
  actually holds much more data than the PCI::Address structure. This is
  fundamental if we want to do certain types of optimizations, and be
  able to support more features of the PCI bus in the foreseeable
  future.

This patch already has several implications:
- All PCI::Device(s) hold a reference to a DeviceIdentifier structure
  being given originally from the PCI::Access singleton. This means that
  all instances of DeviceIdentifier structures are located in one place,
  and all references are pointing to that location. This ensures that
  locking the operation spinlock will take effect in all the appropriate
  places.
- We no longer support adding PCI host controllers and then immediately
  allow for enumerating it with a lambda function. It was found that
  this method is extremely broken and too much complicated to work
  reliably with the new paradigm being introduced in this patch. This
  means that for Volume Management Devices (Intel VMD devices), we
  simply first enumerate the PCI bus for such devices in the storage
  code, and if we find a device, we attach it in the PCI::Access method
  which will scan for devices behind that bridge and will add new
  DeviceIdentifier(s) objects to its internal Vector. Afterwards, we
  just continue as usual with scanning for actual storage controllers,
  so we will find a corresponding NVMe controllers if there were any
  behind that VMD bridge.
2023-01-26 23:04:26 +01:00
Ben Wiederhake add6be4c64 Kernel: Remove unused includes 2023-01-02 11:06:15 -05:00
Liav A cf3b75e2e6 Kernel: Propagate properly errors from PCI IDE Controller initialization 2023-01-02 04:59:23 -07:00
Timon Kruiper 51b69be970 Kernel/aarch64: Move ifdef in StorageManagement.cpp
The recent changes of removing i386 broke the aarch64 build, and moving
the ifdef fixes the aarch64 build.
2022-12-29 19:32:20 -07:00
Liav A 91db482ad3 Kernel: Reorganize Arch/x86 directory to Arch/x86_64 after i686 removal
No functional change.
2022-12-28 11:53:41 +01:00
Liav A 5ff318cf3a Kernel: Remove i686 support 2022-12-28 11:53:41 +01:00
Liav A d94f3b902c Kernel: Propagate properly errors from ISAIDEController initialization 2022-12-16 10:00:31 +01:00
Liav A 3cc0d60141 Kernel: Split the Ext2FileSystem.{cpp,h} files into smaller components 2022-11-08 02:54:48 -07:00
Timon Kruiper 32f4c8df6c Kernel: Stub more functions to progress aarch64 build 2022-10-26 20:01:45 +02:00
demostanis 3e8b5ac920 AK+Everywhere: Turn bool keep_empty to an enum in split* functions 2022-10-24 23:29:18 +01:00
Liav A 965afba320 Kernel/FileSystem: Add a few missing includes
In preparation to future commits, we need to ensure that
OpenFileDescription.h doesn't include the VirtualFileSystem.h file to
avoid include loops.
2022-10-22 16:57:52 -04:00
Liav A 4e0f85432a Kernel/Storage: Remove the ramdisk implementation
Nobody uses this because the x86 prekernel environment is corrupting the
ramdisk image prior to running the actual kernel. In the future we can
ensure that the prekernel doesn't corrupt the ramdisk if we want to
bring support back. In addition to that, we could just use a RAM based
filesystem to load whatever is needed like in Linux, without the need of
additional filesystem driver.

For the mentioned corruption problem, look at issue #9893.
2022-10-03 11:12:35 +02:00
Liav A aeef1c52bc Kernel: Move PCI IDE driver code to the Arch/x86 directory
That code heavily relies on x86-specific instructions, and while other
CPU architectures and platforms can have PCI IDE controllers, currently
we don't support those, so this code is a special case which needs to be
in the Arch/x86 directory.
In the future it could be put back to the original place when we make it
more generic and suitable for other platforms.
2022-09-20 18:43:05 +01:00
Liav A 948be9674a Kernel: Don't compile ISA IDE controller code in non-x86 builds
The ISA IDE controller code makes sense to be compiled in a x86 build as
it relies on access to the x86 IO space. For other architectures, we can
just omit the code as there's no way we can use that code again.
To ensure we can omit the code easily, we move it to the Arch/x86
directory.
2022-09-20 18:43:05 +01:00
Tim Schumacher 8763dbcccc Everywhere: Remove a bunch of dead write-only variables
LLVM 15 now warns (and thus errors) about this, and there is really no
point in keeping them.
2022-09-16 05:39:28 +00:00
Liav A 2c84466ad8 Kernel/Storage: Introduce new boot device addressing modes
Before of this patch, we supported two methods to address a boot device:
1. Specifying root=/dev/hdXY, where X is a-z letter which corresponds to
a boot device, and Y as number from 1 to 16, to indicate the partition
number, which can be omitted to instruct the kernel to use a raw device
rather than a partition on a raw device.
2. Specifying root=PARTUUID: with a GUID string of a GUID partition. In
case of existing storage device with GPT partitions, this is most likely
the safest option to ensure booting from persistent storage.

While option 2 is more advanced and reliable, the first option has 2
caveats:
1. The string prefix "/dev/hd" doesn't mean anything beside a convention
on Linux installations, that was taken into use in Serenity. In Serenity
we don't mount DevTmpFS before we mount the boot device on /, so the
kernel doesn't really access /dev anyway, so this convention is only a
big misleading relic that can easily make the user to assume we access
/dev early on boot.
2. This convention although resemble the simple linux convention, is
quite limited in specifying a correct boot device across hardware setup
changes, so option 2 was recommended to ensure the system is always
bootable.

With these caveats in mind, this commit tries to fix the problem with
adding more addressing options as well as to remove the first option
being mentioned above of addressing.
To sum it up, there are 4 addressing options:
1. Hardware relative address - Each instance of StorageController is
assigned with a index number relative to the type of hardware it handles
which makes it possible to address storage devices with a prefix of the
commandset ("ata" for ATA, "nvme" for NVMe, "ramdisk" for Plain memory),
and then the number for the parent controller relative hardware index,
another number LUN target_id, and a third number for LUN disk_id.
2. LUN address - Similar to the previous option, but instead we rely on
the parent controller absolute index for the first number.
3. Block device major and minor numbers - by specifying the major and
minor numbers, the kernel can simply try to get the corresponding block
device and use it as the boot device.
4. GUID string, in the same fashion like before, so the user use the
"PARTUUID:" string prefix and add the GUID of the GPT partition.

For the new address modes 1 and 2, the user can choose to also specify a
partition out of the selected boot device. To do that, the user needs to
append the semicolon character and then add the string "partX" where X
is to be changed for the partition number. We start counting from 0, and
therefore the first partition number is 0 and not 1 in the kernel boot
argument.
2022-08-30 00:50:15 +01:00
Andreas Kling 11eee67b85 Kernel: Make self-contained locking smart pointers their own classes
Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
2022-08-20 17:20:43 +02:00
Liav A 1102089f9f Kernel/Storage: Don't hardcode a maximum of 16 partitions per drive
In the near future, we will be able to figure out connections between
storage devices and their partitions, so there's no need to hardcode 16
partitions per storage device - each storage device should be able to
have "infinite" count of partitions in it, and we should be able to use
and figure out about them.
2022-08-14 01:09:03 +01:00
Liav A cb68619b7f Kernel/Storage: Safely increment the Controller atomic ID counter 2022-08-14 01:09:03 +01:00
Liav A 0d6315dcc8 Kernel/Storage: Safely increment the Device atomic minor number 2022-08-14 01:09:03 +01:00
Samuel Bowman 25de9de7dc Kernel+LibPartition: Move GUIDPartitionTable into LibPartition 2022-07-21 20:13:44 +01:00
Samuel Bowman 9053d86b82 Kernel+LibPartition: Move EBRPartitionTable into LibPartition 2022-07-21 20:13:44 +01:00
Samuel Bowman 1a6ef03e4a Kernel+LibPartition: Move MBRPartitionTable into LibPartition 2022-07-21 20:13:44 +01:00
Samuel Bowman 940dde9947 Kernel+LibPartition: Move PartitionTable into LibPartition 2022-07-21 20:13:44 +01:00
Liav A c001e3f567 Kernel/Storage: Move AHCI and IDE code into new subdirectories
We do that to increase clarity of the major and secondary components in
the subsystem. To ensure it's even more understandable, we rename the
files to better represent the class within them and to remove redundancy
in the name.

Also, some includes are removed from the general components of the ATA
components' classes.
2022-07-19 11:07:34 +01:00
Liav A 4744ccbff0 Kernel/Storage: Add LUN address to each StorageDevice
LUN address is essentially how people used to address SCSI devices back
in the day we had these devices more in use. However, SCSI was taken as
an abstraction layer for many Unix and Unix-like systems, so it still
common to see LUN addresses in use. In Serenity, we don't really provide
such abstraction layer, and therefore until now, we didn't use LUNs too.
However (again), this changes, as we want to let users to address their
devices under SysFS easily. LUNs make sense in that regard, because they
can be easily adapted to different interfaces besides SCSI.
For example, for legacy ATA hard drive being connected to the first IDE
controller which was enumerated on the PCI bus, and then to the primary
channel as slave device, the LUN address would be 0:0:1.

To make this happen, we add unique ID number to each StorageController,
which increments by 1 for each new instance of StorageController. Then,
we adapt the ATA and NVMe devices to use these numbers and generate LUN
in the construction time.
2022-07-15 12:29:23 +02:00
Liav A 5ed3f7c6bf Kernel/Storage: Migrate the partition code to use the ErrorOr container
That code used the old AK::Result container, which leads to overly
complicated initialization flow when trying to figure out the correct
partition table type. Instead, when using the ErrorOr container the code
is much simpler and more understandable.
2022-04-28 22:13:54 +02:00
Idan Horowitz 086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Liav A 462618b68c Kernel/Storage: Move Ramdisk code into a separate subdirectory 2022-03-19 13:41:06 +00:00
Liav A 428d4ae337 Kernel/PCI: Break early of controller iteration over devices in OOM case
This is mainly useful when adding an HostController but due to OOM
condition, we abort temporary Vector insertion of a DeviceIdentifier
and then exit the iteration loop to report back the error if occured.
2022-03-14 22:39:09 +01:00
Liav A 3fb289e27d Kernel/PCI: Don't hold spinlocks when doing fast device enumeration
Instead, hold the lock while we copy the contents to a stack-based
Vector then iterate on it without any locking.

Because we rely on heap allocations, we need to propagate errors back
in case of OOM condition, therefore, both PCI::enumerate API function
and PCI::Access::add_host_controller_and_enumerate_attached_devices use
now a ErrorOr<void> return value to propagate errors. OOM Error can only
occur when enumerating the m_device_identifiers vector under a spinlock
and trying to expand the temporary Vector which will be used locklessly
to actually iterate over the PCI::DeviceIdentifiers objects.
2022-03-14 22:39:09 +01:00
Liav A 30eeba1981 Kernel/Storage: Don't try to enumerate PCI adapters if PCI is disabled
If there's no PCI bus, then it's safe to assume that we run on a x86
machine that has an ISA IDE controller in the system. In such case, we
just instantiate a ISAIDEController object that assumes fixed locations
of IDE IO ports.
2022-03-02 18:41:54 +01:00
Idan Horowitz 5a5766be2c Kernel: Remove useless partition UUID length check
UUID::to_string() always returns a string of length 36, so this check
can't fail.
2022-02-16 22:21:37 +01:00
Lenny Maiorani c6acf64558 Kernel: Change static constexpr variables to constexpr where possible
Function-local `static constexpr` variables can be `constexpr`. This
can reduce memory consumption, binary size, and offer additional
compiler optimizations.

These changes result in a stripped x86_64 kernel binary size reduction
of 592 bytes.
2022-02-09 21:04:51 +00:00
Pankaj Raghav d234e6b801 Kernel: Add polling support to NVMe
Add polling support to NVMe so that it does not use interrupt to
complete a IO but instead actively polls for completion. This probably
is not very efficient in terms of CPU usage but it does not use
interrupts to complete a IO which is beneficial at the moment as there
is no MSI(X) support and it can reduce the latency of an IO in a very
fast NVMe device.

The NVMeQueue class has been made the base class for NVMeInterruptQueue
and NVMePollQueue. The factory function `NVMeQueue::try_create` will
return the appropriate queue to the controller based on the polling
boot parameter.

The polling mode can be enabled by adding an extra boot parameter:
`nvme_poll`.
2022-02-02 18:26:59 +01:00
Liav A 308e54bc19 AK+Kernel: Implement UUID mixed endianness support
This is being used by GUID partitions so the first three dash-delimited
fields of the GUID are stored in little endian order but the last two
fields are stored in big endian order, hence it's a representation which
is mixed.
2022-01-29 13:35:54 +02:00
Linus Groh c05feaaa74 Kernel/Storage: Dump detected devices and partitions before PANIC()'ing
If we panic the kernel for a storage-related reason, we might as well be
helpful and print out a list of detected storage devices and their
partitions to help with debugging.

Reasons for such a panic include:
- No boot device with the given name found
- No boot device with the given UUID found
- Failing to open the root filesystem after determining a boot device
2022-01-26 21:34:26 +00:00
Idan Horowitz fa0a052fc6 Kernel: Use PARTUUID: instead of PARTUUID= as the partition uuid prefix
This makes the functionality work again, as we no longer allow any
equal signs inside boot parameter values.
2022-01-25 22:41:17 +02:00
Liav A eb9c8f3895 Kernel/PCI: Add basic support for the VMD PCI bridge device 2022-01-23 01:12:55 +01:00
Idan Horowitz 6402840670 Kernel: Replace {KString => String}::formatted in determine_boot_device 2022-01-13 00:20:08 -08:00
Pankaj Raghav 9ae2285675 Kernel: Make enumerate_disk_partitions function not const
The enumerate_disk_partitions function doesn't need to be const. Remove
the constness and use the newly added `add_partition` function.
2022-01-09 20:18:37 -08:00
mjz19910 3102d8e160 Everywhere: Fix many spelling errors 2022-01-07 10:56:59 +01:00
Brian Gianforcaro 24066ba5ef Kernel: Use MUST + Vector::try_append instead of Vector::append
In preparation for making Vector::append unavailable during
compilation of the Kernel.
2022-01-05 14:04:18 +01:00
Brian Gianforcaro d2ac40bcd7 Kernel: Enumerate PCI devices a single time in StorageManagement
Previously we were enumerating multiple times for each storage type.
We can easily enumerate once instead.
2022-01-03 13:26:12 +01:00
Tom 2251733744 Kernel: Allow specifying partition index with NVMe devices
Since NVME devices end with a digit that indicates the node index we
cannot simply append a partition index. Instead, there will be a "p"
character as separator, e.g. /dev/nvme0n1p3 for the 3rd partition.
So, if the early device name ends in a digit we need to add this
separater before matching for the partition index.

If the partition index is omitted (as is the default) the root file
system is on a disk without any partition table (e.g. using QEMU).

This enables booting from the correct partition on an NVMe drive by
setting the command line variable root to e.g. root=/dev/nvme0n1p1
2022-01-02 22:26:36 +01:00
Pankaj Raghav e99fafb683 Kernel/NVMe: Add initial NVMe driver support
Add a basic NVMe driver support to serenity
based on NVMe spec 1.4.

The driver can support multiple NVMe drives (subsystems).
But in a NVMe drive, the driver can support one controller
with multiple namespaces.

Each core will get a separate NVMe Queue.
As the system lacks MSI support, PIN based interrupts are
used for IO.

Tested the NVMe support by replacing IDE driver
with the NVMe driver :^)
2022-01-01 14:55:58 +01:00
Liav A 9eb08bdb0f Kernel: Make major and minor numbers to be DistinctNumerics
This helps avoid confusion in general, and make constructors, methods
and code patterns much more clean and understandable.
2021-12-23 23:02:39 +01:00
Liav A ed5a4f2938 Kernel/Storage: Restore booting from MBR partitions functionality
We had such functionality in the past, but it was regressed and now is
restored.
2021-11-28 08:05:58 +01:00
Liav A 4dc3617f3c Kernel/Storage: Move all ATA related code to a new subdirectory
Like what happened with the PCI and USB code, this feels like the right
thing to do because we can improve on the ATA capabilities and keep it
distinguished from the rest of the subsystem.
2021-11-13 10:05:22 +01:00
Andreas Kling 79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00