1139749Simp%
2116491Sharti% Copyright 2014, General Dynamics C4 Systems
3116491Sharti%
4116491Sharti% This software may be distributed and modified according to the terms of
5116491Sharti% the GNU General Public License version 2. Note that NO WARRANTY is provided.
6116491Sharti% See "LICENSE_GPLv2.txt" for details.
7116491Sharti%
8116491Sharti% @TAG(GD_GPL)
9116491Sharti%
10116491Sharti
11116491ShartiThis module defines the instances of "PSpaceStorable" objects.
12116491Sharti
13116491Sharti\begin{impdetails}
14116491Sharti
15116491ShartiThis module uses the C preprocessor to select a target architecture.
16116491Sharti
17116491Sharti> {-# LANGUAGE CPP #-}
18116491Sharti
19116491Sharti\end{impdetails}
20116491Sharti
21116491Sharti> module SEL4.Object.Instances where
22116491Sharti
23116491Sharti\begin{impdetails}
24116491Sharti
25116491Sharti> import SEL4.API.Types
26116491Sharti> import SEL4.Machine
27116491Sharti> import SEL4.Object.Structures
28116491Sharti> import SEL4.Model.PSpace
29116491Sharti> import SEL4.Model.StateData
30116491Sharti> import SEL4.Object.Instances.TARGET()
31116491Sharti> import SEL4.Config
32116491Sharti
33116491Sharti> import Data.Bits
34116519Sharti
35116519Sharti\end{impdetails}
36116519Sharti
37116491Sharti\subsection{Type Class Instances}
38116491Sharti
39116491ShartiThe following are the instances of "Storable" for the four main types of kernel object: synchronous IPC endpoints, notification objects, thread control blocks, and capability table entries.
40116491Sharti
41116491Sharti\subsubsection{Synchronous IPC Endpoint}
42116491Sharti
43116491Sharti> instance PSpaceStorable Endpoint where
44116491Sharti>     makeObject = IdleEP
45116491Sharti>     injectKO   = KOEndpoint
46116491Sharti>     projectKO o = case o of
47116491Sharti>         KOEndpoint e -> return e
48116491Sharti>         _ -> typeError "Endpoint" o
49116491Sharti
50116491Sharti\subsubsection{Notification objects}
51116491Sharti
52116491Sharti> instance PSpaceStorable Notification where
53116491Sharti>     makeObject = NTFN IdleNtfn Nothing
54116491Sharti>     injectKO   = KONotification
55116491Sharti>     projectKO o = case o of
56116491Sharti>         KONotification e -> return e
57116491Sharti>         _ -> typeError "Notification" o
58116491Sharti
59116491Sharti\subsubsection{Capability Table Entry}
60116491Sharti
61116491Sharti> instance PSpaceStorable CTE where
62116491Sharti>     makeObject = CTE {
63116491Sharti>         cteCap = NullCap,
64116491Sharti>         cteMDBNode = nullMDBNode }
65116491Sharti>     injectKO   = KOCTE
66116491Sharti>     projectKO o = case o of
67116491Sharti>         KOCTE e -> return e
68116491Sharti>         _ -> typeError "CTE" o
69116491Sharti
70119280Simp\begin{impdetails}
71119280SimpAs mentioned in the documentation for the type class "PSpaceStorable", there is one kernel object which needs its own definitions for "loadObject" and "storeObject"; it is the capability table entry. The reason for this is that thread control blocks contain capability table entries for the root of the capability and page tables; the capability copy and revocation functions need to access those "CTE"s while unaware that they are actually inside a "TCB". So the "CTE" versions of "loadObject" and "storeObject" must be able to handle accesses to "TCB"s as well.
72116491Sharti\end{impdetails}
73116491Sharti
74116491Sharti>     loadObject ptr ptr' next obj = case obj of
75116491Sharti>         KOCTE cte -> do
76116491Sharti>             unless (ptr == ptr') $ fail "no CTE found in pspace at address"
77116491Sharti>             alignCheck ptr (objBits cte)
78116491Sharti>             sizeCheck ptr next (objBits cte)
79116491Sharti>             return cte
80116491Sharti>         KOTCB tcb -> do
81116491Sharti>             alignCheck ptr' (objBits tcb)
82116491Sharti>             sizeCheck ptr' next (objBits tcb)
83116491Sharti>             offsetReturn (ptr - ptr') tcb
84116491Sharti>         _ -> typeError "CTE" obj
85116491Sharti>         where
86116491Sharti>             toOffset slot = slot `shiftL` objBits (undefined :: CTE)
87116491Sharti>             offsetReturn x tcb
88116491Sharti>                 | x == toOffset tcbVTableSlot = return $ tcbVTable tcb
89116491Sharti>                 | x == toOffset tcbCTableSlot = return $ tcbCTable tcb
90116491Sharti>                 | x == toOffset tcbReplySlot = return $ tcbReply tcb
91116491Sharti>                 | x == toOffset tcbCallerSlot = return $ tcbCaller tcb
92116491Sharti>                 | x == toOffset tcbIPCBufferSlot =
93116491Sharti>                     return $ tcbIPCBufferFrame tcb
94116491Sharti>                 | otherwise = fail "incorrect CTE offset into TCB"
95116491Sharti
96116491Sharti>     updateObject cte oldObj ptr ptr' next = case oldObj of
97116491Sharti>         KOCTE _ -> do
98116491Sharti>             unless (ptr == ptr') $ fail "no CTE found in pspace at address"
99116491Sharti>             alignCheck ptr (objBits cte)
100116491Sharti>             sizeCheck ptr next (objBits cte)
101116491Sharti>             return (KOCTE cte)
102116491Sharti>         KOTCB tcb -> do
103116491Sharti>             alignCheck ptr' (objBits tcb)
104116491Sharti>             sizeCheck ptr' next (objBits tcb)
105116491Sharti>             offsetAdjust (ptr - ptr') tcb
106116491Sharti>         _ -> typeError "CTE" oldObj
107116491Sharti>         where
108116491Sharti>             toOffset slot = slot `shiftL` objBits (undefined :: CTE)
109116491Sharti>             offsetAdjust x tcb
110116491Sharti>                 | x == toOffset tcbVTableSlot
111116491Sharti>                     = return $ KOTCB (tcb {tcbVTable = cte})
112116491Sharti>                 | x == toOffset tcbCTableSlot
113116491Sharti>                     = return $ KOTCB (tcb {tcbCTable = cte})
114116491Sharti>                 | x == toOffset tcbReplySlot
115116491Sharti>                     = return $ KOTCB (tcb { tcbReply = cte })
116116491Sharti>                 | x == toOffset tcbCallerSlot
117116491Sharti>                     = return $ KOTCB (tcb { tcbCaller = cte })
118116491Sharti>                 | x == toOffset tcbIPCBufferSlot
119148887Srwatson>                     = return $ KOTCB (tcb { tcbIPCBufferFrame = cte })
120116491Sharti>                 | otherwise = fail "incorrect CTE offset into TCB"
121116491Sharti
122116491Sharti\subsubsection{Thread Control Block}
123116491Sharti
124116491ShartiThe value of "objBits" in this instance is an estimate; the value used in real implementations may vary and may be architecture-dependent.
125116491ShartiBy default, new threads are unable to change the security domains of other threads. They are later placed in the correct security domain by "createObject".
126116491Sharti
127116491Sharti> instance PSpaceStorable TCB
128116491Sharti>   where
129116491Sharti>     makeObject = Thread {
130116491Sharti>         tcbCTable = makeObject,
131116491Sharti>         tcbVTable = makeObject,
132116491Sharti>         tcbReply = makeObject,
133116491Sharti>         tcbCaller = makeObject,
134116491Sharti>         tcbIPCBufferFrame = makeObject,
135116491Sharti>         tcbDomain = minBound,
136116491Sharti>         tcbState = Inactive,
137116491Sharti>         tcbMCP = minBound,
138116491Sharti>         tcbPriority = minBound,
139116491Sharti>         tcbQueued = False,
140116491Sharti>         tcbFault = Nothing,
141116491Sharti>         tcbTimeSlice = timeSlice,
142116491Sharti>         tcbFaultHandler = CPtr 0,
143116491Sharti>         tcbIPCBuffer = VPtr 0,
144116491Sharti>         tcbBoundNotification = Nothing,
145116491Sharti>         tcbArch = newArchTCB }
146116491Sharti>     injectKO   = KOTCB
147116491Sharti>     projectKO o = case o of
148116491Sharti>         KOTCB tcb -> return tcb
149116491Sharti>         _ -> typeError "TCB" o
150116491Sharti
151116491Sharti\subsubsection{User Data}
152116491Sharti
153116491Sharti> instance PSpaceStorable UserData where
154116491Sharti>     makeObject = UserData
155116491Sharti>     injectKO  _ = KOUserData
156116491Sharti>     projectKO o = case o of
157116491Sharti>         KOUserData -> return UserData
158116491Sharti>         _ -> typeError "UserData" o
159116491Sharti
160116491Sharti> instance PSpaceStorable UserDataDevice where
161116491Sharti>     makeObject = UserDataDevice
162118598Sharti>     injectKO _ = KOUserDataDevice
163116491Sharti>     projectKO o = case o of
164116491Sharti>         KOUserDataDevice -> return UserDataDevice
165116491Sharti>         _ -> typeError "UserDataDevice" o
166116491Sharti
167116491Sharti
168116491Sharti
169116491Sharti