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