Add a helper initialize_interrupt_queue() helper to enable_irq instead
of doing it as part of its object construction as it can fail. This is
similar to how AHCI initializes its interrupt as well.
NVMe{Poll|Interrupt}Queue don't have a try_create() method. Add one to
keep it consistent with how we create objects. Also this commit is in
preparation to moving any initialization related code out of the
constructor.
This commit lets us differentiate whether access faults are caused by
accessing junk memory addresses given to us by userspace or if we hit a
kernel bug.
The stub implementations of the `safe_*` functions currently don't let
us jump back into them and return a value indicating failure, so we
panic if such a fault happens. Practically, this means that we still
crash, but if the access violation was caused by something else, we take
the usual kernel crash code path and print a register and memory dump,
rather than hitting the `TODO_AARCH64` in `handle_safe_access_fault`.
These are used in futexes, which are needed if we want to get further in
`run-tests`.
For now, we have no way to return a non-fatal error if an access fault
is raised while executing these, so the kernel will panic. Some would
consider this a DoS vulnerability where a malicious userspace app can
crash the kernel by passing bogus pointers to it, but I prefer to call
it progress :^)
Enabling these will fix the Unsupported Exclusive or Atomic access data
fault we get on bare metal Raspberry Pi 3. On A53/A57 chips (and newer),
atomic compare-exchange operations require the data cache to be enabled.
Referencing ARM DDI 0487J.a, update the names of previously reserved
fields, and set the reset_value() of the SCTLR_EL1 struct to reflect
the defaults we want for this register on reboot.
... key-value decomposition
The RaspberryPi firmware will give us a value for the 'video' key that
contains multiple equal signs:
```
video=HDMI-A-1:1920x1080M@30D,margin_left=48,margin_right=48,[...]
```
Instead of asserting that this only has one equal sign, let's just split
it by the first one.
Remove the hardcoded "AHCI Scattered DMA" for region name as it is a
part of a common API. Add region_name parameter to the try_create API
so that this API can be used by other drivers with the correct Memory
region name.
The constructor code of ScatterGatherList had code that can return
error. Move it to try_create for better error propagation.
This removes one TODO() and one
release_value_but_fixme_should_propagate_errors().
This removes the TODO from the try_create API to return ErrorOr. This
is also a preparation patch to move the init code in the constructor
that can fail to this try_create function.
These 2 are an actual separate types of syscalls, so let's stop using
special flags for bind mounting or re-mounting and instead let userspace
calling directly for this kind of actions.
The Multiboot header stores the framebuffer's pitch in bytes, so
multiplying it by the pixel's size is not necessary. We ended up
allocating 4 times as much memory as needed, which caused us to overlap
the MMIO reserved memory area on the Raspberry Pi.
Otherwise, the message's contents might be in the cache only, so
VideoCore will read stale/garbage data from main memory.
This fixes framebuffer setup on bare metal with the data cache enabled.
While the PL011-based UART0 is currently reserved for the kernel
console, UART1 is free to be exposed to the userspace as `/dev/ttyS0`.
This will be used as the stdout of `run-tests-and-shutdown.sh` when
testing the AArch64 kernel.
The Raspberry Pi hardware doesn't support a proper software-initiated
shutdown, so this instead uses the watchdog to reboot to a special
partition which the firmware interprets as an immediate halt on
shutdown. When running under Qemu, this causes the emulator to exit.
We now have everything in the AArch64 kernel to be able to use the full
`__panic` implementation, so we can share the code with x86-64.
I have kept `__assertion_failed` separate for now, as the x86-64 version
directly executes inline assembly, thus `Kernel/Arch/aarch64/Panic.cpp`
could not be removed.
Extend reserve_irqs, allocate_irq, enable_interrupt and
disable_interrupt API to add MSI support in PCI device.
The current changes only implement single MSI message support.
TODOs have been added to support Multiple MSI Message (MME) support in
the future.
Add a struct named MSIInfo that stores all the relevant MSI
information as a part of PCI DeviceIdentifier struct.
Populate the MSI struct during the PCI device init.
These functions would have caused a `-Woverloaded-virtual` warning with
GCC 13, as they shadow `File::{attach,detach}(OpenFileDescription&)`.
Both of these functions had a single call site. This commit inlines
`attach` into its only caller, `FIFO::open_direction`.
Instead of explicitly checking `is_fifo()` in `~OpenFileDescription`
before running the `detach(Direction)` overload, let's just override the
regular `detach(OpenFileDescription&)` for `FIFO` to perform this action
instead.
This logo was actually used as a first sign of life in the very early
days of the aarch64 port.
Now that we boot into the graphical mode of the system just fine there's
no need to keep this.
This is in preparation for adding MSI(x) support to the NVMe device.
NVMeInterruptQueue needs access to the PCI device to deal with MSI(x)
interrupts. It is ok to pass the NVMeController as a reference to the
NVMeQueue as NVMeController is the one that owns the NVMeQueue.
This is very similar to how AHCIController passes its reference to its
interrupt handler.
Add an explicit QueueType enum which could be used to create a poll or
an interrupt queue. This is better than passing an Optional<irq>.
This refactoring is in preparation for adding MSIx support to NVMe.
PCIIRQHandler is a generic IRQ handler that the device driver can
inherit to use either Pin or MSI(x) based interrupt mechanism.
The PCIIRQHandler can do what the existing IRQHandler can do for pin
based interrupts but also deal with MSI based interrupts. We can
hopefully convert all the PCI based devices to use this handler so that
MSI(x) can be used.
Add reserve_irqs, allocate_irq, enable_interrupt and disable_interrupt
API to a PCI device.
reserve_irqs() can be used by a device driver that would like to
reserve irqs for MSI(x) interrupts. The API returns the type of IRQ
that was reserved by the PCI device. If the PCI device does not support
MSI(x), then it is a noop.
allocate_irq() API can be used to allocate an IRQ at an index. For
MSIx the driver needs to map the vector table into the memory and add
the corresponding IRQ at the given index. This API will return the
actual IRQ that was used so that the driver can use it create interrupt
handler for that IRQ.
{enable, disable}_interrupt API is used to enable or disable a
particular IRQ at the given index. It is a noop for pin-based
interrupts. This could be used by IRQHandler to enable or disable an
interrupt.
MSIx table entry is used to program interrupt vectors and it is
architecture specific. Add helper functions declaration in
Arch/PCIMSI.h. The definition of the function is placed in the
respective arch specific code.
Add a struct named MSIxInfo that stores all the relevant MSIx
information as a part of PCI DeviceIdentifier struct.
Populate the MSIx struct during the PCI device init. As the
DeviceIdentifier struct need to populate MSIx info, don't mark
DeviceIdentifier as const in the PCI::Device class.
MSI(x) interrupts need to reserve IRQs so that it can be programmed by
the device. Add an API to reserve contiguous ranges of interrupt
handlers so that it can used by PCI devices that use MSI(x) mechanism.
This API needs to be implemented by aarch64 architecture.
Set pin-based interrupt handler as reserved during PCI bus init.
This is required so that MSI(x) based interrupts can avoid sharing the
IRQ which has been marked as reserved.
Pin-based PCI device are allocated an IRQ, and it could be shared with
multiple devices. An interrupt handler with an IRQ for a PCI device
will get registered only during the driver initialization.
For MSI(x) interrupts, the driver has to allocate IRQs and this field
can be used to skip IRQs that have already been reserved by pin-based
interrupts so that we don't have to share IRQs, which generally will
reduce the performance.
"The official project language is American English […]."
5d2e915623/CONTRIBUTING.md (L30)
Here's a short statistic of the occurrences of the word "behavio(u)r":
$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
2 BEHAVIOR
24 Behaviour
32 behaviour
407 Behavior
992 behavior
Therefore, it is clear that "behaviour" (56 occurrences) should be
regarded a typo, and "behavior" (1401 occurrences) should be preferred.
Note that The occurrences in LibJS are intentionally NOT changed,
because there are taken verbatim from the specification. Hence:
$ git grep -IPioh 'behaviou?r' | sort | uniq -c | sort -n
2 BEHAVIOR
10 behaviour
24 Behaviour
407 Behavior
1014 behavior
This was discovered by me during a work on USB keyboard patches, so it
triggered this bug.
The printing format for the VirtualAddress part is incorrect, leading to
another crash when handling page fault after accessing UNMAP_AFTER_INIT
code section.
Whenever an entry is added to the cache, the last element is removed to
make space for the new entry(if the cache is full). To make this an LRU
cache, the entry needs to be moved to the front of the list when there
is a cache hit so that the least recently used entry moves to the end
to be evicted first.