1
2\section{Introduction}
3
4\subsection{Purpose}
5
6The goal of the \acs{ahci} Flounder backend is twofold: first, it should allow
7specifying \ac{ata} messages declaratively, making adding messages easier and
8reducing the amount of code potentially containing bugs. Second, sending such
9\ac{ata} messages to a disk should behave just like general-purpose
10inter-dispatch messaging, enabling transparent proxying of messages should no
11direct connection be available between a dispatcher and a suitable I/O
12controller.
13
14\subsection{Design}
15
16However, our use of Flounder also represents a major extension to its purpose.
17So far, Flounder transports have simply been responsible for transferring data,
18i.e. marshalling, packaging and transmission. Our backend differs in that it
19must understand the purpose of each data item: depending on that purpose, it
20must be formatted in a particular way, other actions may be necessary, and
21certain restrictions (in particular on the size and type of the data) may
22apply.
23
24What this means for our project is that we must extend Flounder's syntax with
25message meta-data, i.e. parameters providing additional information about a
26message definition but not contributing to the runtime message payload. An
27example of our current syntax can be seen in figure~\ref{fig:flounder-example}.
28
29\begin{figure}[htb]
30\begin{center}
31\begin{lstlisting}
32interface ata_rw28 "ATA read & write with 28-bit LBA" {
33
34    @ata(command=0xC8, dma_arg=buffer, dma_size=read_size,
35         lba=start_lba)
36    rpc read_dma(in uint32 read_size, in uint32 start_lba,
37                 out uint8 buffer[buffer_size]);
38
39    @ata(command=0xC8, dma_arg=buffer, dma_size=512, lba=lba)
40    rpc read_dma_block(in uint32 lba, out uint8 buffer[buffer_size]);
41
42    @ata(command=0xCA, dma_arg=buffer, is_write=1, lba=lba)
43    rpc write_dma(in uint8 buffer[buffer_size], in uint32 lba,
44                  out errval status);
45
46    @ata(command=0xEC, dma_arg=buffer, dma_size=512)
47    rpc identify_device(out uint8 buffer[buffer_size]);
48
49    @ata(command=0xE7)
50    rpc flush_cache(out errval status);
51};
52\end{lstlisting}
53\caption{Example \acs{ata} message definitions}
54\label{fig:flounder-example}
55\end{center}
56\end{figure}
57
58\section{Discussion}
59
60\subsection{Targeting: Compiler vs. Topic}
61
62As seen in the syntax example, a set of meta-parameters is targeted using the
63``@'' notation. Two possibilities exist for the interpretation of the target
64specifier:
65
66\begin{itemize}
67
68	\item The target may specify a compiler name (e.g. \verb+@AHCI_Stubs+),
69		with each compiler receiving only the meta-parameters targeted to it.
70		Among other things, this requires an additional step between parsing
71		and compiling, thus a compiler no longer receives the interface
72		definition's full AST.
73
74		Also, compilers are unable to share such parameters, e.g. if backends
75		exist for different \ac{ata} command transports, parameters related to
76		formatting of \ac{ata} commands must be repeated for each backend's
77		compiler.
78
79	\item The target may specify a generic ``topic''.  This does not require
80		the extra preprocessing step and allows sharing of meta-parameters, but
81		requires compilers to match their interpretation of shared parameters.
82		Nonetheless, the sharing of parameters (also between header and stub
83		compilers of the same backend) may make this solution preferable.
84
85\end{itemize}
86
87While the initial implementation used the former solution, this was replaced
88and we now use the second option.
89
90\subsection{Parameter Analysis}
91
92Extracting information from parameters and meta-parameters can be done in
93various ways. Their presence, absence, type and (for meta-parameters) value can
94all be used as sources of information. The question is therefore how best to
95handle this information, as demonstrated in the following examples:
96
97\begin{itemize}
98
99	\item The presence of an output parameter \lstinline+status+ of type
100		\lstinline+errval_t+ may imply that it should be used for a status
101		result. But what if the type is different, or there is a
102		\lstinline+errval_t+-typed parameter with a different name?
103
104	\item The size of a buffer may be extracted from its type if that is an
105		array typedef. If it is a dynamic array, the may be the dynamic length
106		parameter. In either case, the size might also be specified as a
107		meta-parameter. Which of these information sources should be accepted?
108
109\end{itemize}
110
111\section{Generated Interface}
112\newcommand{\flifname}{\textit{if\_name}}
113\newcommand{\flahcib}{\flifname\lstinline+_ahci_binding+\xspace}
114
115\subsection{Initialization}
116
117Initialization is done with \flifname\lstinline+_ahci_init+. The client must
118first initialize libahci, at which point the target device is specified with
119the \lstinline+port+ parameter of \lstinline+ahci_init+. Also, the client must
120allocate a suitable \flahcib.
121
122\subsection{Binding Type}
123
124The \flahcib\ type extends the generic binding type, allowing the generated
125\acs{ahci} bindings to be used anywhere the generic binding type is used. In
126particular, the RPCClient can be wrapped around \acs{ahci} bindings, greatly
127simplifying their usage.
128
129Additionally, an \acs{ahci} binding contains a libahci binding, used internally
130for communication with the library.
131
132\subsection{Interface methods}
133
134Because \acs{ahci} Flounder bindings use the generic binding as a base, the
135generic messaging methods can be used, with the \flahcib cast to the generic
136\flifname\lstinline+_binding+.
137
138\section{Implementation}
139
140\subsection{Command Completion}
141
142To generate Flounder responses, the \ac{ahci} backend must associate command
143completion callbacks from libahci with information from the original command.
144This is done using libahci's command tags; before issuing a command, a
145\lstinline+completed_rx_st+ ``command completion'' struct is allocated and
146filled. The address of this struct is sent as the command tag for
147\lstinline+issue_command+. Upon command completion, the tag is cast to a
148\lstinline+completed_rx_st+, and the \lstinline+completed_fn+ callback function
149pointer is called.
150
151The \lstinline+completed_rx_st+ contains information for the message-specific
152completion handler. Currently, this consists of the \flahcib and the region
153used for \acs{dma}. If the message is supposed to perform a \acs{dma} read, the
154data must be copied out of the \acs{dma} region into an allocated buffer to be
155passed to the client. If \acs{dma} is used at all, the region must also be
156freed.
157
158Finally, the \lstinline+completed_rx_st+ is used by the
159\lstinline+issue_command_cb+ for freeing the allocated \ac{fis} and calling the
160message send user continuation.
161
162\subsection{DMA Handling}
163
164When parameter analysis indicates a \acs{dma} transfer is expected, the
165\ac{ahci} backend must generate code to setup \acs{dma} regions, copying in TX
166data before issuing the command, and copying out RX data after the command
167completes.
168
169To perform \acs{dma}, a \lstinline+dma_arg+ must be specified in the
170\lstinline+ata+-targeted message meta-arguments. When the \ac{ahci} backend
171detects this argument, it expects the value to be an identifier that
172corresponds to one of the formal message arguments. The \acs{dma} direction is
173then the direction of that message argument; \lstinline+in+ is a transmit,
174\lstinline+out+ is a receive.
175
176Because the \acs{dma} region must be allocated before the command is issued, if
177a \acs{dma} argument is present, the size of the \acs{dma} must either be
178specified in the interface file, or must be determinable upon receiving the rpc
179call from the client. The size of the \acs{dma} may therefore be specified with
180any of the following means:
181
182\begin{itemize}
183	\item If \lstinline+dma_arg+ is a dynamic array, its size argument is used.
184		(transmit only)
185	\item If \lstinline+dma_arg+'s type is an array of fixed size, that is
186		used.
187	\item If a meta-argument \lstinline+dma_size+ is present and is an integer,
188		that is used.
189	\item If a meta-argument \lstinline+dma_size+ is present and is an
190		identifier, the \acs{rpc} must have an \lstinline+in+ argument with
191		that name, the value of which is used.
192\end{itemize}
193
194Finally, the \acs{dma} data must be copied in and out of suitably mapped
195regions, managed using libahci's \lstinline+ahci_dma_region+ API. This is
196necessary because flounder semantics require that the client owns buffer
197memory.
198
199\subsection{FIS Setup}
200
201To issue a command over \ac{ahci}, the \acs{ahci} backend must first set up a
202suitable \ac{fis}.  This is done using the \lstinline+sata_fis+ API in libahci.
203