aos/doc/015-disk-driver-arch/xahcid.tex
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

70 lines
3.2 KiB
TeX

\label{chap:ahcid}
\section{Introduction}
\subsection{Public IDC Interface}
ahcid's design is modeled after netd. It has a small \acs{idc} interface that
facilitates user access to a port: when registering for a port, the user is
given the capability for the port registers. Interrupts are forwarded via
\acs{idc} messages. Currently the interface also provides access to the {\tt
IDENTIFY} data of all available disks. This is useful to determine the type of
device and total disk space without having to open the port.
\begin{center}
\begin{minipage}{100mm}
\begin{lstlisting}[label={code:ahci_mgmt.if}, caption={ahci management Flounder
interface}]
interface ahci_mgmt "AHCI Management Daemon" {
rpc list(out uint8 port_ids[len]);
rpc identify(in uint8 port_id,
out uint8 identify_data[data_len]);
rpc open(in uint8 port_id, out errval status,
out cap controller_mem, out
uint64 offset, out uint32 capabilities);
rpc close(in uint8 port_id, out errval status);
message command_completed(uint8 port_id,
uint32 interrupt_status);
};
\end{lstlisting}
\end{minipage}
\end{center}
\section{Initialization}
ahcid registers itself as a driver for the \ac{ahci} device class. Once the
init procedure is called, ahcid consults the received base address registers to
find the memory region used for the \acs{hba}'s registers.
As a first step, the \ac{hba} is reset in order to get to a known state. The
\ac{hba} is also put into \ac{ahci} mode. After the initial reset, ahcid
discovers the number of ports and detects which of them are implemented and
have a disk connected. Discovered disks are assigned a system-wide unique port
id and are registered with the skb. For every disk, an \ac{ata} {\tt IDENTIFY}
command is sent to determine the disk's parameters. A copy of the {\tt
IDENTIFY} response is cached in ahcid for later use.
After all attached disks are initialized, ahcid exports the ahci management
interface, which clients can then use to register themselves for a single port.
\section{Interrupt Handling}
ahcid registers itself as an interrupt handler for the \ac{ahci} \ac{hba}
controller when calling \lstinline+pci_register_driver_irq+. The interrupt
handler extracts the current interrupt state of the controller from the device
memory and decides if the interrupt was triggered by the \ac{hba}. If the
interrupt was triggered by the \ac{hba}, the handler loops over all ports and
checks which ports received an interrupt and clears the port's interrupt
register. The \ac{hba}'s interrupt register is cleared after all port interrupt
registers have been cleared. At last, if a client is registered for a port that
has received an interrupt, ahcid sends a \lstinline+command_completed+ message
(\autoref{code:ahci_mgmt.if}) using the established \lstinline+ahci_mgmt+
interface. Clearing the interrupts before delivering the completion messages to
the respective users ensures that we do not miss interrupts that would be
triggered as a consequence of any commands issued in the command completion
handler. Missing any interrupts for further completions could deadlock a user
since we do not poll the port's state if no interrupts have been triggered.