On the QEMU microvm machine type, it became apparent that the BIOS was
not setting the i8042 controller to function as expected. To ensure that
the controller is always outputting correct scan codes, set it to scan
code 2 and enable first port translation to ensure all scan codes are
translated to scan code set 1. This is the expected behavior when using
SeaBIOS, but on qboot (the BIOS for the QEMU microvm machine type), the
firmware doesn't take care of this so we need to do this ourselves.
Some error indication was done by returning bool. This was changed to
propagate the error by ErrorOr from the underlying functions. The
returntype of the underlying functions was also changed to propagate the
error.
Expose the block size variable via a member function in the
AsyncBlockDeviceRequest so that the driver doesn't need to assume any
value such as 512 bytes.
This will replace the /dev/tty symlink created by SystemServer, so
instead of a symlink, a character device will be created. When doing
read(2), write(2) and ioctl(2) on this device, it will "redirect" these
operations to the attached TTY of the current process.
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.
We now only reset the PCM out channel during initialization, and handle
the case where the channel's current index has passed the last valid
index properly.
This fixes issues with stuttering audio between multiple subsequent
`aplay` invocations, for example.
This might help with debugging on bare metal. Since the minimum version
that can be specified is revision 2.1, and we do not use any feature
from revision 2.2 or newer, this is merely future-proofing ourselves
for new features yet to be built. Additionally, removing the `VERIFY()`
ensures we will not crash on cards that only support earlier revisions.
The Qemu AC'97 device stops its PCM channel's DMA engine when it is
running and the sample rate is changed. We now make sure the DMA engine
is restarted after changing the sample rate, allowing you to e.g. run
`asctl set r 22050` during `aplay` playback.
This driver is not tested and probably not used on any modern hardware
machine, because it is plugged into the ISA bus and not the PCI bus.
Also, the run script doesn't utilize this device anymore, making it more
hard to test this driver and to ensure it doesn't rot.
Some hardware controllers might reset when trying to do self-test, so
keep the configuration byte to restore it later on.
To ensure we are not missing the response from the i8042 controller,
bump the attempts count to 20 times after initiating self-test check.
Also, try to drain the i8042 controller output buffer as it might be a
early good indication on whether i8042 is present or not.
To ensure we drain all the output buffer, we attempt to read from the
buffer 50 times and not 20 times.
This is very similar to the change that was done in 32053e8, except it
turned out that the new limit of 50 iterations was not enough when
testing on bare metal - most IO operations would succeed in the first or
second iteration, but two of them took 140 and 150 iterations
respectively.
Increase the limit from 50 to 250 to account for this, and have some
additional headroom.
This caused an initialization failure of the i8042 when I tested on
bare metal. We cannot entirely get rid of this method as QEMU for
example doesn't indicate the existence of an i8042 via ACPI, but we can
get away with only doing the manual probing if ACPI is disabled or we
didn't get a 'yes' from it.
Increasing the number of maximum loops did eventually lead to a
successful return from the function, but would later fail the actual
self test.
The SB16 card driver doesn't swallow more than 4096 bytes of data at
once, so instead of asserting just return ENOSPC for now.
To test this, either play normal sound or just this (very!) loud noise:
dd if=/dev/random of=/dev/audio/0 bs=4096
We have 3 new components:
1. The AudioManagement singleton. This class like in other subsystems,
is responsible to find hardware audio controllers and keep a reference
to them.
2. AudioController class - this class is the parent class for hardware
controllers like the Sound Blaster 16 or Intel 82801AA (AC97). For now,
this class has simple interface for getting and controlling sample rate
of audio channels, as well a write interface for specific audio channel
but not reading from it. One AudioController object might have multiple
AudioChannel "child" objects to hold with reference counting.
3. AudioChannel class - this is based on the CharacterDevice class, and
represents hardware PCM audio channel. It facilitates an ioctl interface
which should be consistent across all supported hardware currently.
It has a weak reference to a parent AudioController, and when trying to
write to a channel, it redirects the data to the parent AudioController.
Each audio channel device should be added into a new directory under the
/dev filesystem called "audio".
Since we're in an IRQ each of these evaluate_block_conditions() calls
enqueues a new deferred call, so to save on some space in the deferred
call queue let's just do it once.
Apparently on VirtualBox the keyboard device refused to complete the
reset sequence. With longer delays and more attempts before giving up,
it seems like the problem is gone.
Not only does it makes the code more robust and correct as it allows
error propagation, it allows us to enforce timeouts on waiting loops so
we don't hang forever, by waiting for the i8042 controller to respond to
us.
Therefore, it makes the i8042 more resilient against faulty hardware and
bad behaving chipsets out there.
If we don't do so, we just hang forever because we assume there's i8042
controller in the system, which is not a valid assumption for modern PC
hardware.
As make<T> is infallible, it really should not be used anywhere in the
Kernel. Instead replace with fallible `new (nothrow)` calls, that will
eventually be error-propagated.
We currently support the left super key. This poses an issue on
keyboards that only have a right super key, such as my Steelseries 6G.
The implementation mirrors the left/right shift key logic and
effectively considers the right super key identical to the left one.
Devices such as NVMe can have blocks bigger that 512. Use the
m_block_size variable in read/write_block function instead of the
hardcoded 512 block size.
This makes sure DeviceManagement::try_create_device will call the
static factory function (if available) instead of directly calling the
constructor, which will allow us to move OOM-fallible calls out of
Device constructors.
This device will assist userspace to manage hotplug events.
A userspace application reads a DeviceEvent entry until the return value
is zero which indicates no events that are queued and waiting for
processing.
Trying to read with a buffer smaller than sizeof(DeviceEvent) results in
EOVERFLOW.
For now, there's no ioctl mechanism for this device but in the future an
acknowledgement mechanism can be implemented via ioctl(2) interface.
This was easily done, as the Kernel and Userland don't actually share
any of the APIs exposed by it, so instead the Kernel APIs were moved to
the Kernel, and the Userland APIs stayed in LibKeyboard.
This has multiple advantages:
* The non OOM-fallible String is not longer used for storing the
character map name in the Kernel
* The kernel no longer has to link to the userland LibKeyboard code
* A lot of #ifdef KERNEL cruft can be removed from LibKeyboard
This mostly just moved the problem, as a lot of the callers are not
capable of propagating the errors themselves, but it's a step in the
right direction.
This was broken in commit 0a1b34c753 / PR #11687 since the buffer
descriptor list size was not page-aligned, and the new
`MM.allocate_dma_buffer_pages` expects a page-aligned size.
Although we can still consider this impossible to happen now, because
the mmap syscall entry code verifies that specified offset must be page
aligned, it's still a good practice to VERIFY we actually take a start
address as page-aligned in case of doing mmap on /dev/mem.
As for read(2) on /dev/mem, we don't map anything to userspace so it's
safe to read from whatever offset userspace specified as long as it does
not break the original rules of reading physical memory from /dev/mem.
So far we only had mmap(2) functionality on the /dev/mem device, but now
we can also do read(2) on it.
The test unit was updated to check we are doing it safely.
Previously, one could put '\b' in a keymap, but in non-Terminal
applications, it would just insert a literal '\b' character instead of
behaving like backspace. This patch modifes
`visible_code_point_to_key_code` to include backspace, as well as
renaming it to `code_point_to_key_code` since '\b' is not a visible
character. Additionally, `KeyboardDevice::key_state_changed` has been
rearranged to apply the user's keymap before checking for things like
caps lock.
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 :^)
This will allow File and it's descendants to use RefCounted instead of
having a custom implementation of unref. (Since RefCounted calls
will_be_destroyed automatically)
This commit also removes an erroneous call to `before_removing` in
AHCIPort, this is a duplicate call, as the only reference to the device
is immediately dropped following the call, which in turns calls
`before_removing` via File::unref.
This was a premature optimization from the early days of SerenityOS.
The eternal heap was a simple bump pointer allocator over a static
byte array. My original idea was to avoid heap fragmentation and improve
data locality, but both ideas were rooted in cargo culting, not data.
We would reserve 4 MiB at boot and only ended up using ~256 KiB, wasting
the rest.
This patch replaces all kmalloc_eternal() usage by regular kmalloc().
This fixes at least half of our LibC includes in the kernel. The source
of truth for errno codes and their description strings now lives in
Kernel/API/POSIX/errno.h as an enumeration, which LibC includes.
Instead, allocate before constructing the object and pass NonnullOwnPtr
of KString to the object if needed. Some classes can determine their
names as they have a known attribute to look for or have a static name.
The fixes are:
1. Don't copy PCI::DeviceIdentifier during construction. This is a heavy
structure to copy so we definitely don't want to do that. Instead, use
a const reference to it like what happens in other parts in the Kernel.
2. Declare the constructor as explicit to avoid construction errors.
Previously we `VERIFY()`ed that the device supports variable-rate audio
(VRA). Now, we query the VRA bit and if VRA is not supported, we do not
enable double-rate audio and disallow setting any sample rate except
the fixed 48kHz rate as defined by the AC'97 specification. This should
allow the driver to function on a wider array of hardware.
Note that in the AC'97 specification, DRA without VRA is allowed when
supported: this effectively doubles the sample rate to 96kHZ. For now,
we ignore that possibility and let it default to 48kHZ.
Before, only KeyEvent::code_point took the user's keyboard layout
into consideration, while KeyEvent::key was hardcoded QWERTY. This
affected, among other things, Vim Emulation.
Now, KeyEvent::key respects the user's keyboard layout, so will be the
same as KeyEvent::code_point for visible (alphanumeric + symbol) keys.
Co-Authored-By: Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
Executing `asctl set r 96000` no longer results in weird sample rates
being set on the audio devices. SB16 checks for a sample rate between 1
and 44100 Hz, while AC97 implements double-rate support which allows
sample rates between 8kHz and 96kHZ.
This factors out some hardcoded PCMOut registers into a new private
class called AC97Channel, which wraps around a channel's registers and
provides some shared functionality.
No functional changes.
As soon as we enable the first PS/2 port on the I8042 controller, the
output buffer may become full. We need to drain it before attempting
any new commands with the controller (such as enabling the second PS/2
port).
Fixes#10872.
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. :^)
The Qemu I8042 controller does not send one IRQ per event, it sends
over four since it will not stop trying to emulate the PS/2 mouse.
If the VMWare backdoor is active, a fake I8042 mouse event will be sent
that we can then use to check if there are VMWare mouse events present.
However, we were only processing one mouse event at a time, even though
multiple events could have been queued up. Luckily this does not often
lead to issues, since after the first IRQ we would still get three
additional interrupts that would then empty the queue.
This change makes sure we always empty the event queue immediately,
instead of waiting on the next interrupt to happen. Functionally this
changes nothing - it could merely improve latency by not waiting for
new interrupts to come in.
Coincidently, this brings our implementation closer to how Linux deals
with the VMMouse.
This reverts commit 4131b35851.
We're swallowing way too many mouse events from QEMU with this code
enabled. Something is not right, so let's revert it for now.
Found due to smelly code in InodeFile::absolute_path.
In particular, this replaces the following misleading methods:
File::absolute_path
This method *never* returns an actual path, and if called on an
InodeFile (which is impossible), it would VERIFY_NOT_REACHED().
OpenFileDescription::try_serialize_absolute_path
OpenFileDescription::absolute_path
These methods do not guarantee to return an actual path (just like the
other method), and just like Custody::absolute_path they do not
guarantee accuracy. In particular, just renaming the method made a
TOCTOU bug obvious.
The new method signatures use KResultOr, just like
try_serialize_absolute_path() already did.
Bit 3 is set here:
c5b2f55981/hw/input/ps2.c (L736)
Spurious mouse packets can be received without this bit set, for
example when double-clicking and keeping the mouse button depressed
instead of releasing it the second time (i.e. mousedown > mouseup >
mousedown). We should not process such packets.
This makes interaction with our buttons much smoother!
Fixes#5881.
Instead of detecting which flag was set in the status register, we can
use the instrument type passed to us. This works because the mouse and
keyboard use different IRQs.
A new RegisterState header includes the platform specific RegisterState
header based on the platform being compiled.
The Aarch64 RegisterState header contains stubs for Debug
Previously there was a mix of returning plain strings and returning
explicit string views using `operator ""sv`. This change switches them
all to standardized on `operator ""sv` as it avoids a call to strlen.
Currently, writing anything to `/dev/mouse0` or `/dev/keyboard0` causes
the Kernel to panic. The reason for this is that
`[Mouse,Keyboard]Device::write` always returns 0, which is explicitly
prohibited by `VERIFY` macro in `Process::sys$write`. The fix seems
trivial; `write` should return EINVAL instead (as is the case with, for
example, `KCOVDevice`).