1This chapter details the ways the \ac{ahci} driver can be 
2run and elaborates on the adjustments needed to be able to 
3run the driver on real hardware.
4
5\section{QEMU}
6
7Since version 0.14, QEMU contains an emulation layer for an \acs{ich}-9
8\ac{ahci} controller\footnote{The QEMU 0.14 changelog is available at
9\url{http://wiki.qemu.org/ChangeLog/0.14}}. To define a disk, the QEMU command
10line needs to be extended with:
11
12\begin{lstlisting}[language=bash]
13 -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 \
14 -drive id=disk,file=/path/to/disk.img,if=none
15\end{lstlisting}
16
17QEMU emulates an \acs{ich}-9 controller sufficiently well that little special
18code is required. A first workaround is needed for finding the \ac{ahci}
19\acs{pci} \ac{bar}; since the QEMU \ac{ahci} emulation layer does not provide
20the legacy IDE compatibility mode, the \ac{ahci} MMIO region is found in
21\ac{bar} 0 instead of \ac{bar} 5. Another workaround is necessary when
22receiving the response for an {\tt IDENTIFY}, which is a PIO command but is
23delivered as a Device to Host Register \ac{fis} by QEMU.
24
25\section{Physical Hardware}
26
27Running Barrelfish on real hardware, one can run into several issues. In order
28to be able to test our \ac{ahci} implementation, we had to adjust several
29aspects of Barrelfish outside the scope of the \ac{ahci} driver infrastructure.
30This chapter details any additional modifications.
31
32\subsection{PCI Base Address Registers}
33
34Barrelfish's system knowledge base is not able to handle addresses above 32 bit
35correctly. Fixing this issue would require extensive modifications in the
36\acs{skb} which are out of the scope of this lab project. As a consequence,
37\emph{ahcid} will receive zero \acp{bar} on hardware where the \ac{ahci} memory
38regions are mapped in memory above 4GB and thus be unable to access the memory
39mapped I/O region to control the \ac{hba}. For the same reason, the code produced by
40this lab project has not been tested for 64bit addresses in memory mapped I/O
41regions.  Still, once the issues in the \acs{hba} have been fixed, the driver should
42properly recognise and handle the devices in question.
43
44\subsection{PCI Bridge Programming}
45
46Because of a bug in \acs{pci} bridge programming, Barrelfish sometimes does not
47program \acs{pci} \acp{bar} correctly if \acs{pci} bridges are present. For
48this lab project, we introduce a workaround that will retrieve the original
49\acp{bar} in case no reprogrammed \acp{bar} can be found in the \acs{skb}.
50
51This is achieved in the \lstinline+device_init+ function of \lstinline+pci.c+,
52by querying the \acs{skb} for the original \lstinline+bar(...)+ facts of the
53device if no reprogrammed ones can be found:
54
55\begin{lstlisting}
56error_code = skb_execute_query(
57  "findall(baraddr(BAR,Base,0,Size),bar(addr(%u,%u,%u)"
58  ",BAR,Base,Size,_,_,_), BARList),"
59  "sort(1, =<, BARList, L),"
60  "length(L,Len),writeln(L)",
61  *bus, *dev, *fun);
62\end{lstlisting}
63
64The result of this prolog expression has exactly the same form as
65\lstinline+pci_get_+\linebreak \lstinline+implemented_BAR_addresses+ therefore
66the surrounding code is exactly the same as in the usual case.
67
68\subsection{BIOS Memory Maps}
69
70On x86 architectures, the BIOS memory map can be retrieved to determine the
71layout of memory. Some BIOSs report a memory map that is not sorted by
72increasing base address or even might return overlapping and conflicting memory
73regions.  This lab project contains modifications to the code that creates
74capabilities to physical memory in \verb+startup_arch.c+ such that the memory
75map is preprocessed to eliminate conflicts and ensure ascending addresses.
76
77As the preprocessed memory map might be larger due to the case where one memory
78region completely contains another and thus is split into three new regions, we
79first need to copy the map into a larger buffer. The memory map is then sorted
80with a simple bubblesort.  To remove conflicts, overlapping regions are given
81to the region with the higher type or merged if they are both of the same type.
82At the end, regions are page-aligned as Barrelfish can only map whole pages.
83
84\autoref{fig:mmap} shows the memory maps seen on a DELL Optiplex 755
85workstation. Several regions are not aligned to the pagesize and the region at
86\lstinline+0xfec00000+ does not appear in ascending order. After preprocessing,
87memory addresses appear in ascending order and are page-aligned. Note that
88higher types take precedence, therefore page alignment does not necessarily
89round down.
90
91\begin{figure}[ht]
92\centering
93\includegraphics[width=.7\textwidth]{mmap.pdf}
94\caption{Memory map transformation}
95\label{fig:mmap}
96\end{figure}
97