Double kfree() is exceedingly rare in our kernel since we use automatic
memory management and smart pointers for almost all code. However, it
doesn't hurt to do some basic checking that might one day catch bugs.
This patch makes us VERIFY that we don't already consider the first
chunk of a kmalloc() allocation free when kfree()'ing it.
I dont know why we do a fast path in the Kernel, but not in Userspace
Also simplified the byte explosion in memset to "explode_byte"
it even seemed so, that we missed the highest byte when memseting something
The first one is for disabling the PS2 controller, the other one is for
disabling physical storage enumeration.
We can't be sure any machine will work with our implementation,
therefore this will help us to test more machines.
We need to do it to let real hardware to put the correct voltages
on the wire.
Apparently my ICH7 machine refused to boot, and was reading lots of
garbage from an unconnected IDE channel. It was fixed after I added a
delay of 20 microseconds. It probably can be reduced, I just took a safe
value and it seems to work correctly without any problems :)
Now the kernel supports 2 ECAM access methods.
MMIOAccess was renamed to WindowedMMIOAccess and is what we had until
now - each device that is detected on boot is assigned to a
memory-mapped window, so IO operations on multiple devices can occur
simultaneously due to creating multiple virtual mappings, hence the name
is a memory-mapped window.
This commit adds a new class called MMIOAccess (not to be confused with
the old MMIOAccess class). This class creates one memory-mapped window.
On each IO operation on a configuration space of a device, it maps the
requested PCI bus region to that window. Therefore it holds a SpinLock
during the operation to ensure that no other PCI bus region was mapped
during the call.
A user can choose to either use PCI ECAM with memory-mapped window
for each device, or for an entire bus. By default, the kernel prefers to
map the entire PCI bus region.
Apparently we don't enable PCI ECAM (MMIO access to the PCI
configuration space) even if we can. This is a regression, as it was
enabled in the past and in unknown time it was regressed.
The CommandLine::is_mmio_enabled method was renamed to
CommandLine::is_pci_ecam_enabled to better represent the meaning
of this method and what it determines.
Also, an UNMAP_AFTER_INIT macro was removed from a method
in the MMIOAccess class as it halted the system when the kernel
tried to access devices after the boot process.
The end goal of this commit is to allow to boot on bare metal with no
PS/2 device connected to the system. It turned out that the original
code relied on the existence of the PS/2 keyboard, so VirtualConsole
called it even though ACPI indicated the there's no i8042 controller on
my real machine because I didn't plug any PS/2 device.
The code is much more flexible, so adding HID support for other type of
hardware (e.g. USB HID) could be much simpler.
Briefly describing the change, we have a new singleton called
HIDManagement, which is responsible to initialize the i8042 controller
if exists, and to enumerate its devices. I also abstracted a bit
things, so now every Human interface device is represented with the
HIDDevice class. Then, there are 2 types of it - the MouseDevice and
KeyboardDevice classes; both are responsible to handle the interface in
the DevFS.
PS2KeyboardDevice, PS2MouseDevice and VMWareMouseDevice classes are
responsible for handling the hardware-specific interface they are
assigned to. Therefore, they are inheriting from the IRQHandler class.
This reverts commit 36a82188a8.
This register is write-only for the firmware (BIOS), and read-only for
us so we shouldn't set the PCI IRQ line never.
The firmware figured out the IRQ routing to the PIC for us, so changing
it won't affect anything. I was mistaken when I thought that changing
the value of this register will allow us to change its interrupt line,
like when changing a PCI BAR to relocate device resources as desired
with the requirements of the OS.
Also handle native and compatibility channel modes together, so if only
one IDE channel was set to work on PCI native mode, we need to handle it
separately, so the other channel continue to operate with the legacy IO
ports and interrupt line.
This is done also by linux (signal.c:936 in v5.11) at least.
It's a pretty handy notification that allows the parent process to skip
going through a `waitpid` and guesswork to figure out the current state
of a child process.
Added a dummy TIOCSTI ioctl placeholder. This is a dangerous ioctl that
can be used to inject input into a tty. Added for compatibility. Always
fails with EIO.
Previously, Process::do_write would error if the O_APPEND flag was set
on a non-seekable file.
Other systems (such as Linux) seem to be OK with doing this, so we now
do not attempt to seek to the end the file if it's not seekable.
Most coredumps contain large amounts of consecutive null bytes and as
such are a prime candidate for compression.
This commit makes CrashDaemon compress files once the kernel finishes
emitting them, as well as adds the functionality needed in LibCoreDump
to then parse them.
This is a "quirk" I've observed on a Intel ICH7 test machine. Apparently
we need to select the device (master or slave) before starting to work
with the bus master register.
It's very possible that other machines are requiring this step to happen
before the DMA transfer can occur correctly.
Also, when reading with DMA, we should set the transfer direction before
clearing the interrupt status.
For the sake of completeness, I added a few lines in places that I
deemed it to be reasonable to clear the interrupt status there.
Although unlikely to happen, a user can have an IDE controller that
doesn't support bus master capability. If that's the case, we need to
check for this, and create an IDEChannel (not BMIDEChannel) to allow
IO operations with the controller.
If the user requests to force PIO mode, we just create IDEChannel
objects which are capable of sending PIO commands only.
However, if the user doesn't force PIO mode, we create BMIDEChannel
objects, which are sending DMA commands.
This change is somewhat simplifying the code, so each class is
supporting its type of operation - PIO or DMA. The PATADiskDevice
should not care if DMA is enabled or not.
Later on, we could write an IDEChannel class for UDMA modes,
that are available and documented on Intel specifications for their IDE
controllers.
Technically not supported by the original ATA specification, IDE
hot swapping is still in practice possible, so the only sane way
to start support it is with ref-counting the IDEChannel object so if we
remove a PATADiskDevice, it's not gone with it.
An article about IDE limits states that:
"Hard drives over 8.4 GB are supposed to report their geometry as
16383/16/63. This in effect means that the `geometry' is obsolete, and
the total disk size can no longer be computed from the geometry, but is
found in the LBA capacity field returned by the IDENTIFY command.
Hard drives over 137.4 GB are supposed to report an LBA capacity of
0xfffffff = 268435455 sectors (137438952960 bytes). Now the actual disk
size is found in the new 48-capacity field."
(https://tldp.org/HOWTO/Large-Disk-HOWTO-4.html) which is the main
reason to not support CHS as harddrives with less than 8.4 GB capacity
are completely obsolete.
Another good reason is that virtually any harddrive in the last 20 years
or so, supports LBA mode. Therefore, it's probably OK to just ignore CHS
as it's unlikely to encounter a harddrive that doesn't support LBA.
This is somewhat simplifying the IDE initialization and access code.
Also, we should use the ATAIdentifyBlock structure if possible,
so now we do it instead of using macros to calculate offsets.
With the usage of the ATAIdentifyBlock structure, we now use the
48-bit LBA max count if the drive indicates it supports 48-bit LBA mode.
This reverts commit cfc2f33dcb.
We can't actually change the IRQ line value and expect the device
to work with it (this was my mistake).
That register is R/W so the firmware can figure out IRQ routing and put
the correct value and write it to the Interrupt line register.
As a compromise, if the fimrware decided to set the IRQ line to be 7,
or something else we can't deal with, the user can simply force the code
to work with IRQ 11, with the boot argument "force_ahci_irq_11" being
set to "on".