updated translated haskell spec
This commit is contained in:
parent
002cf370bb
commit
7b6ddc5212
|
@ -161,7 +161,7 @@ begin
|
|||
|
||||
definition
|
||||
makeObject_asidpool: "(makeObject :: asidpool) \<equiv> ASIDPool $
|
||||
funArray (const Nothing)"
|
||||
funPartialArray (const Nothing) (0,1023)"
|
||||
|
||||
definition
|
||||
loadObject_asidpool[simp]:
|
||||
|
|
|
@ -27,46 +27,61 @@ consts
|
|||
idleThreadCode :: "machine_word list"
|
||||
|
||||
consts
|
||||
initKernelVM :: "unit kernel"
|
||||
mapKernelWindow :: "unit kernel"
|
||||
|
||||
consts
|
||||
initVSpace :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
createGlobalPD :: "unit kernel"
|
||||
|
||||
consts
|
||||
activateGlobalPD :: "unit kernel"
|
||||
|
||||
consts
|
||||
mapKernelRegion :: "(paddr * paddr) \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
mapKernelFrame :: "paddr \<Rightarrow> vptr \<Rightarrow> vmrights \<Rightarrow> vmattributes \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
allocKernelPT :: "(machine_word) kernel"
|
||||
createSectionPDE :: "vptr \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
mapKernelDevice :: "(paddr * machine_word) \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
createGlobalsFrame :: "unit kernel"
|
||||
activateGlobalPD :: "unit kernel"
|
||||
|
||||
consts
|
||||
createITPDPTs :: "capability \<Rightarrow> vptr \<Rightarrow> vptr \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
writeITPDPTs :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
createITASIDPool :: "capability \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
writeITASIDPool :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
mapITPTCap :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
mapITFrameCap :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
createIPCBufferFrame :: "capability \<Rightarrow> vptr \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
createBIFrame :: "capability \<Rightarrow> vptr \<Rightarrow> word32 \<Rightarrow> word32 \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
createITFrameCap :: "machine_word \<Rightarrow> vptr \<Rightarrow> asid option \<Rightarrow> bool \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
createFramesOfRegion :: "capability \<Rightarrow> region \<Rightarrow> bool \<Rightarrow> vptr \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
mapGlobalsFrame :: "unit kernel"
|
||||
|
||||
consts
|
||||
createInitialRoot :: "machine_word \<Rightarrow> capability kernel_init"
|
||||
writeIdleCode :: "unit kernel"
|
||||
|
||||
consts
|
||||
populateInitialRoot :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel_init"
|
||||
mapKernelFrame :: "paddr \<Rightarrow> vptr \<Rightarrow> vmrights \<Rightarrow> vmattributes \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
allocUserPT :: "asid \<Rightarrow> vptr \<Rightarrow> (machine_word) kernel_init"
|
||||
getARMGlobalPT :: "(machine_word) kernel"
|
||||
|
||||
consts
|
||||
mapUserFrame :: "machine_word \<Rightarrow> asid \<Rightarrow> paddr \<Rightarrow> vptr \<Rightarrow> unit kernel_init"
|
||||
createDeviceFrames :: "capability \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
copyGlobalMappings :: "machine_word \<Rightarrow> unit kernel"
|
||||
|
@ -146,12 +161,6 @@ isValidVTableRoot :: "capability \<Rightarrow> bool"
|
|||
consts
|
||||
checkValidIPCBuffer :: "vptr \<Rightarrow> capability \<Rightarrow> ( syscall_error , unit ) kernel_f"
|
||||
|
||||
consts
|
||||
createInitPage :: "paddr \<Rightarrow> capability kernel"
|
||||
|
||||
consts
|
||||
createDeviceCap :: "(paddr * paddr) \<Rightarrow> capability kernel"
|
||||
|
||||
consts
|
||||
maskVMRights :: "vmrights \<Rightarrow> cap_rights \<Rightarrow> vmrights"
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ defs kernelBase_def:
|
|||
"kernelBase \<equiv> VPtr 0xf0000000"
|
||||
|
||||
defs globalsBase_def:
|
||||
"globalsBase \<equiv> VPtr 0xff000000"
|
||||
"globalsBase \<equiv> VPtr 0xffffc000"
|
||||
|
||||
defs idleThreadStart_def:
|
||||
"idleThreadStart \<equiv> globalsBase + VPtr 0x100"
|
||||
|
@ -36,62 +36,22 @@ defs idleThreadCode_def:
|
|||
, 0xeafffffc
|
||||
]"
|
||||
|
||||
defs initKernelVM_def:
|
||||
"initKernelVM\<equiv> (do
|
||||
createGlobalPD;
|
||||
allMemory \<leftarrow> doMachineOp getMemoryRegions;
|
||||
mapM_x mapKernelRegion allMemory;
|
||||
kernelDevices \<leftarrow> doMachineOp getKernelDevices;
|
||||
mapM_x mapKernelDevice kernelDevices;
|
||||
createGlobalsFrame;
|
||||
mapGlobalsFrame;
|
||||
activateGlobalPD
|
||||
od)"
|
||||
|
||||
defs initVSpace_def:
|
||||
"initVSpace cRootSlot vRootSlot\<equiv> (do
|
||||
provideRegion $ BootRegion
|
||||
(CPtr $ fromVPtr kernelBase) maxBound BRCapsOnly 0;
|
||||
vRoot \<leftarrow> createInitialRoot vRootSlot;
|
||||
cRoot \<leftarrow> doKernelOp $ getSlotCap cRootSlot;
|
||||
populateInitialRoot vRoot cRoot;
|
||||
doKernelOp $ doMachineOp cleanCaches_PoU
|
||||
od)"
|
||||
|
||||
defs createGlobalPD_def:
|
||||
"createGlobalPD\<equiv> (do
|
||||
globalPD \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
deleteObjects (PPtr $ fromPPtr globalPD) pdBits;
|
||||
placeNewObject (PPtr $ fromPPtr globalPD) (makeObject ::pde)
|
||||
(pdBits `~shiftR~` (objBits (makeObject ::pde)));
|
||||
globalPTs \<leftarrow> gets $ armKSGlobalPTs \<circ> ksArchState;
|
||||
deleteObjects (PPtr $ fromPPtr $ head globalPTs) pageBits;
|
||||
placeNewObject (PPtr $ fromPPtr $ head globalPTs) (makeObject ::pte)
|
||||
(pageBits `~shiftR~` (objBits (makeObject ::pte)));
|
||||
return ()
|
||||
od)"
|
||||
|
||||
defs activateGlobalPD_def:
|
||||
"activateGlobalPD\<equiv> (do
|
||||
doMachineOp cleanCaches_PoU;
|
||||
globalPD \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
doMachineOp $ (do
|
||||
setCurrentPD $ addrFromPPtr globalPD;
|
||||
invalidateTLB
|
||||
od)
|
||||
od)"
|
||||
|
||||
defs mapKernelRegion_def:
|
||||
"mapKernelRegion x0\<equiv> (case x0 of
|
||||
(phys, physEnd) \<Rightarrow> (do
|
||||
magnitude \<leftarrow> return ( physEnd - phys);
|
||||
defs mapKernelWindow_def:
|
||||
"mapKernelWindow\<equiv> (do
|
||||
vbase \<leftarrow> return ( kernelBase `~shiftR~` pageBitsForSize (ARMSection));
|
||||
pdeBits \<leftarrow> return ( objBits (undefined ::pde));
|
||||
haskell_assert (magnitude \<ge> bit (pageBitsForSize ARMSection))
|
||||
[];
|
||||
pteBits \<leftarrow> return ( objBits (undefined ::pte));
|
||||
ptSize \<leftarrow> return ( ptBits - pteBits);
|
||||
pdSize \<leftarrow> return ( pdBits - pdeBits);
|
||||
globalPD \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
if (magnitude < bit (pageBitsForSize ARMSuperSection))
|
||||
then forM_x [phys, phys + bit (pageBitsForSize ARMSection) .e. phys + magnitude - 1] (\<lambda> phys. (do
|
||||
virt \<leftarrow> return ( VPtr $ fromPPtr $ ptrFromPAddr phys);
|
||||
globalPTs \<leftarrow> gets $ armKSGlobalPTs \<circ> ksArchState;
|
||||
deleteObjects (PPtr $ fromPPtr globalPD) pdBits;
|
||||
placeNewObject (PPtr $ fromPPtr globalPD) (makeObject ::pde) pdSize;
|
||||
forM_x [vbase, vbase+16 .e. (bit pdSize) - 16 - 1] $ createSectionPDE;
|
||||
forM_x [(bit pdSize) - 16, (bit pdSize) - 2] (\<lambda> v. (do
|
||||
offset \<leftarrow> return ( fromVPtr v);
|
||||
virt \<leftarrow> return ( v `~shiftL~` pageBitsForSize (ARMSection));
|
||||
phys \<leftarrow> return ( addrFromPPtr $ PPtr $ fromVPtr virt);
|
||||
pde \<leftarrow> return ( SectionPDE_ \<lparr>
|
||||
pdeFrame= phys,
|
||||
pdeParity= True,
|
||||
|
@ -100,226 +60,334 @@ defs mapKernelRegion_def:
|
|||
pdeGlobal= True,
|
||||
pdeExecuteNever= False,
|
||||
pdeRights= VMKernelOnly \<rparr>);
|
||||
offset \<leftarrow> return ( fromVPtr virt `~shiftR~` pageBitsForSize ARMSection);
|
||||
slot \<leftarrow> return ( globalPD + PPtr (offset `~shiftL~` pdeBits));
|
||||
storePDE slot pde
|
||||
od))
|
||||
else forM_x [phys, phys + bit (pageBitsForSize ARMSuperSection) .e. phys + magnitude - 1] (\<lambda> phys. (do
|
||||
virt \<leftarrow> return ( VPtr $ fromPPtr $ ptrFromPAddr phys);
|
||||
pde \<leftarrow> return ( SuperSectionPDE_ \<lparr>
|
||||
pdeFrame= phys,
|
||||
pdeParity= True,
|
||||
pdeCacheable= True,
|
||||
pdeGlobal= True,
|
||||
pdeExecuteNever= False,
|
||||
pdeRights= VMKernelOnly \<rparr>);
|
||||
offset \<leftarrow> return ( fromVPtr virt `~shiftR~` pageBitsForSize ARMSection);
|
||||
slots \<leftarrow> return ( map (\<lambda> n. globalPD + PPtr (n `~shiftL~` pdeBits))
|
||||
[offset .e. offset + 15]);
|
||||
mapM_x (flip storePDE pde) slots
|
||||
od))
|
||||
od)
|
||||
)"
|
||||
|
||||
defs mapKernelFrame_def:
|
||||
"mapKernelFrame paddr vptr rights attributes\<equiv> (do
|
||||
haskell_assert (vptr \<ge> kernelBase) [];
|
||||
pd \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
pdSlot \<leftarrow> return ( lookupPDSlot pd vptr);
|
||||
pde \<leftarrow> getObject pdSlot;
|
||||
pteBits \<leftarrow> return ( objBits (undefined ::pte));
|
||||
ptIndex \<leftarrow> return ( fromVPtr $ vptr `~shiftR~` 12 && 0xff);
|
||||
ptSlot \<leftarrow> (case pde of
|
||||
PageTablePDE _ _ _ \<Rightarrow> (do
|
||||
pt \<leftarrow> return ( ptrFromPAddr $ pdeTable pde);
|
||||
return $ pt + (PPtr $ ptIndex `~shiftL~` pteBits)
|
||||
od)
|
||||
| InvalidPDE \<Rightarrow> (do
|
||||
ptFrame \<leftarrow> allocKernelPT;
|
||||
pde \<leftarrow> return ( PageTablePDE_ \<lparr>
|
||||
pdeTable= addrFromPPtr ptFrame,
|
||||
pdeParity= True,
|
||||
pdeDomain= 0 \<rparr>);
|
||||
storePDE pdSlot pde;
|
||||
return $ PPtr $ fromPPtr ptFrame + (ptIndex `~shiftL~` pteBits)
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
pte \<leftarrow> getObject ptSlot;
|
||||
(case pte of
|
||||
InvalidPTE \<Rightarrow> (do
|
||||
pte' \<leftarrow> return ( SmallPagePTE_ \<lparr>
|
||||
pteFrame= paddr,
|
||||
pteCacheable= armPageCacheable attributes,
|
||||
pteGlobal= True,
|
||||
pteExecuteNever= False,
|
||||
pteRights= rights \<rparr>);
|
||||
storePTE ptSlot pte'
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
od));
|
||||
paddr \<leftarrow> return ( addrFromPPtr $ PPtr $ fromPPtr $ head globalPTs);
|
||||
pde \<leftarrow> return ( PageTablePDE_ \<lparr>pdeTable= paddr ,pdeParity= True, pdeDomain= 0\<rparr>);
|
||||
slot \<leftarrow> return ( globalPD + PPtr (((bit pdSize) - 1) `~shiftL~` pdeBits));
|
||||
deleteObjects (PPtr $ fromPPtr $ head globalPTs) ptBits;
|
||||
placeNewObject (PPtr $ fromPPtr $ head globalPTs) (makeObject ::pte) ptSize;
|
||||
storePDE slot pde;
|
||||
mapGlobalsFrame;
|
||||
kernelDevices \<leftarrow> doMachineOp getKernelDevices;
|
||||
mapM_x mapKernelDevice kernelDevices
|
||||
od)"
|
||||
|
||||
defs allocKernelPT_def:
|
||||
"allocKernelPT\<equiv> (do
|
||||
pts \<leftarrow> gets $ armKSGlobalPTs \<circ> ksArchState;
|
||||
(case pts of
|
||||
[] \<Rightarrow> haskell_fail []
|
||||
| (pt#pts') \<Rightarrow> (do
|
||||
modify (\<lambda> ks. ks \<lparr>
|
||||
ksArchState := (ksArchState ks) \<lparr> armKSGlobalPTs := pts' \<rparr> \<rparr>);
|
||||
return pt
|
||||
od)
|
||||
)
|
||||
defs createSectionPDE_def:
|
||||
"createSectionPDE v\<equiv> (do
|
||||
vbase \<leftarrow> return ( kernelBase `~shiftR~` pageBitsForSize (ARMSection));
|
||||
pdeBits \<leftarrow> return ( objBits (undefined ::pde));
|
||||
pteBits \<leftarrow> return ( objBits (undefined ::pte));
|
||||
globalPD \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
offset \<leftarrow> return ( fromVPtr v);
|
||||
virt \<leftarrow> return ( (v - vbase) `~shiftL~` (pageBitsForSize (ARMSuperSection) - 4));
|
||||
phys \<leftarrow> return ( addrFromPPtr $ PPtr $ fromVPtr virt);
|
||||
pde \<leftarrow> return ( SuperSectionPDE_ \<lparr>
|
||||
pdeFrame= phys,
|
||||
pdeParity= True,
|
||||
pdeCacheable= True,
|
||||
pdeGlobal= True,
|
||||
pdeExecuteNever= False,
|
||||
pdeRights= VMKernelOnly \<rparr>);
|
||||
slots \<leftarrow> return ( map (\<lambda> n. globalPD + PPtr (n `~shiftL~` pdeBits))
|
||||
[offset .e. offset + 15]);
|
||||
(flip $ mapM_x ) slots (\<lambda> slot. storePDE slot pde)
|
||||
od)"
|
||||
|
||||
defs mapKernelDevice_def:
|
||||
"mapKernelDevice x0\<equiv> (case x0 of
|
||||
(addr, ptr) \<Rightarrow> (do
|
||||
vptr \<leftarrow> return ( VPtr $ fromPPtr ptr);
|
||||
mapKernelFrame addr vptr VMKernelOnly $ VMAttributes False False False
|
||||
mapKernelFrame addr vptr VMKernelOnly $ VMAttributes False False True
|
||||
od)
|
||||
)"
|
||||
|
||||
defs createGlobalsFrame_def:
|
||||
"createGlobalsFrame\<equiv> (do
|
||||
globals \<leftarrow> gets $ armKSGlobalsFrame \<circ> ksArchState;
|
||||
deleteObjects (PPtr $ fromPPtr globals) pageBits;
|
||||
reserveFrame (PPtr $ fromPPtr globals) True;
|
||||
offset \<leftarrow> return ( fromVPtr $ idleThreadStart - globalsBase);
|
||||
doMachineOp $ mapM_x
|
||||
(split storeWord
|
||||
)
|
||||
(zipE2 (globals + PPtr offset) ( globals + PPtr offset + 4) (idleThreadCode))
|
||||
defs activateGlobalPD_def:
|
||||
"activateGlobalPD\<equiv> (do
|
||||
globalPD \<leftarrow> gets $ armKSGlobalPD \<circ> ksArchState;
|
||||
doMachineOp $ (do
|
||||
setCurrentPD $ addrFromPPtr globalPD;
|
||||
invalidateTLB
|
||||
od)
|
||||
od)"
|
||||
|
||||
defs createITPDPTs_def:
|
||||
"createITPDPTs rootCNCap vptrStart biFrameVPtr\<equiv> (do
|
||||
pdSize \<leftarrow> return ( pdBits - objBits (makeObject ::pde));
|
||||
ptSize \<leftarrow> return ( ptBits - objBits (makeObject ::pte));
|
||||
pdPPtr \<leftarrow> allocRegion pdBits;
|
||||
doKernelOp $ placeNewObject (ptrFromPAddr pdPPtr) (makeObject::pde) pdSize;
|
||||
pdCap \<leftarrow> return $ ArchObjectCap $ PageDirectoryCap (ptrFromPAddr pdPPtr) (Just itASID);
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapITPD;
|
||||
doKernelOp $ insertInitCap slot $ pdCap;
|
||||
slotBefore \<leftarrow> noInitFailure $ gets $ initSlotPosCur;
|
||||
btmVPtr \<leftarrow> return ( vptrStart `~shiftR~` (pdSize + pageBits) `~shiftL~` (pdSize + pageBits));
|
||||
step \<leftarrow> return ( 1 `~shiftL~` (ptSize + pageBits));
|
||||
topVPtr \<leftarrow> return ( biFrameVPtr + (bit biFrameSizeBits) - 1);
|
||||
forM_x [btmVPtr,btmVPtr + step .e. topVPtr] (\<lambda> vptr. (do
|
||||
ptPPtr \<leftarrow> allocRegion ptBits;
|
||||
doKernelOp $ placeNewObject (ptrFromPAddr ptPPtr) (makeObject::pte) ptSize;
|
||||
provideCap rootCNCap $ ArchObjectCap $ PageTableCap (ptrFromPAddr ptPPtr) (Just (itASID, vptr))
|
||||
od));
|
||||
slotAfter \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
bootInfo \<leftarrow> noInitFailure $ gets initBootInfo;
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifUIPTCaps := [slotBefore .e. slotAfter - 1] \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr> initBootInfo := bootInfo' \<rparr>);
|
||||
return pdCap
|
||||
od)"
|
||||
|
||||
defs writeITPDPTs_def:
|
||||
"writeITPDPTs rootCNCap pdCap \<equiv>
|
||||
(case pdCap of
|
||||
ArchObjectCap cap \<Rightarrow> (do
|
||||
doKernelOp $ copyGlobalMappings $ capPDBasePtr cap;
|
||||
ptSlots \<leftarrow> noInitFailure $ gets $ bifUIPTCaps \<circ> initBootInfo;
|
||||
doKernelOp $ (
|
||||
(flip mapM) ptSlots (\<lambda> pos. (do
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) pos;
|
||||
cte \<leftarrow> getCTE slot;
|
||||
mapITPTCap pdCap (cteCap cte)
|
||||
od)
|
||||
)
|
||||
);
|
||||
frameSlots \<leftarrow> noInitFailure $ gets $ bifUIFrameCaps \<circ> initBootInfo;
|
||||
doKernelOp $ (do
|
||||
(flip mapM) frameSlots (\<lambda> pos. (do
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) pos;
|
||||
cte \<leftarrow> getCTE slot;
|
||||
mapITFrameCap pdCap (cteCap cte)
|
||||
od)
|
||||
);
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapITIPCBuf;
|
||||
cte \<leftarrow> getCTE slot;
|
||||
mapITFrameCap pdCap (cteCap cte);
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapBIFrame;
|
||||
cte \<leftarrow> getCTE slot;
|
||||
mapITFrameCap pdCap (cteCap cte)
|
||||
od)
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail $ (show pdCap) @ []
|
||||
)"
|
||||
|
||||
defs createITASIDPool_def:
|
||||
"createITASIDPool rootCNCap\<equiv> (do
|
||||
apPPtr \<leftarrow> allocRegion $ objBits (undefined ::asidpool);
|
||||
doKernelOp $ placeNewObject (ptrFromPAddr apPPtr) (makeObject::asidpool) 0;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapITASIDPool;
|
||||
asidPoolCap \<leftarrow> return $ ArchObjectCap $ ASIDPoolCap (ptrFromPAddr apPPtr) 0;
|
||||
doKernelOp $ insertInitCap slot asidPoolCap;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapASIDControl;
|
||||
asidControlCap \<leftarrow> return $ ArchObjectCap $ ASIDControlCap;
|
||||
doKernelOp $ insertInitCap slot asidControlCap;
|
||||
return asidPoolCap
|
||||
od)"
|
||||
|
||||
defs writeITASIDPool_def:
|
||||
"writeITASIDPool apCap pdCap\<equiv> (do
|
||||
apPtr \<leftarrow> (case apCap of
|
||||
ArchObjectCap (ASIDPoolCap ptr _) \<Rightarrow> return ptr
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
pdPtr \<leftarrow> (case pdCap of
|
||||
ArchObjectCap (PageDirectoryCap ptr _) \<Rightarrow> return ptr
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
ap \<leftarrow> liftM (inv ASIDPool) $ getObject apPtr;
|
||||
ap' \<leftarrow> return ( ap aLU [(itASID, Just pdPtr)]);
|
||||
setObject apPtr (ASIDPool ap');
|
||||
asidTable \<leftarrow> gets (armKSASIDTable \<circ> ksArchState);
|
||||
asidTable' \<leftarrow> return ( asidTable aLU [(asidHighBitsOf itASID, Just apPtr)]);
|
||||
modify (\<lambda> s. s \<lparr>
|
||||
ksArchState := (ksArchState s) \<lparr> armKSASIDTable := asidTable' \<rparr>\<rparr>)
|
||||
od)"
|
||||
|
||||
defs mapITPTCap_def:
|
||||
"mapITPTCap pdCap ptCap\<equiv> (do
|
||||
pd \<leftarrow> (case pdCap of
|
||||
ArchObjectCap (PageDirectoryCap ptr _) \<Rightarrow> return ptr
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
ptCap' \<leftarrow> (case ptCap of
|
||||
ArchObjectCap c \<Rightarrow> return c
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
(pt,vptr) \<leftarrow> (case ptCap' of
|
||||
PageTableCap pt' (Some (_, vptr')) \<Rightarrow> return (pt', vptr')
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ (show ptCap)
|
||||
);
|
||||
offset \<leftarrow> return ( fromVPtr $ vptr `~shiftR~` pageBitsForSize ARMSection);
|
||||
targetSlot \<leftarrow> return ( pd + (PPtr $ offset `~shiftL~` 2));
|
||||
pde \<leftarrow> return ( PageTablePDE_ \<lparr>
|
||||
pdeTable= addrFromPPtr pt,
|
||||
pdeParity= True,
|
||||
pdeDomain= 0 \<rparr>);
|
||||
storePDE targetSlot pde
|
||||
od)"
|
||||
|
||||
defs mapITFrameCap_def:
|
||||
"mapITFrameCap pdCap frameCap\<equiv> (do
|
||||
pd' \<leftarrow> (case pdCap of
|
||||
ArchObjectCap (PageDirectoryCap ptr _) \<Rightarrow> return ptr
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ (show pdCap)
|
||||
);
|
||||
frameCap' \<leftarrow> (case frameCap of
|
||||
ArchObjectCap c \<Rightarrow> return c
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ (show frameCap)
|
||||
);
|
||||
(frame,vptr) \<leftarrow> (case frameCap' of
|
||||
PageCap frame' _ _ (Some (_, vptr')) \<Rightarrow> return (frame', vptr')
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ (show frameCap)
|
||||
);
|
||||
offset \<leftarrow> return ( fromVPtr $ vptr `~shiftR~` pageBitsForSize ARMSection);
|
||||
pd \<leftarrow> return ( pd' + (PPtr $ offset `~shiftL~` 2));
|
||||
pde \<leftarrow> getObject pd;
|
||||
pt \<leftarrow> (case pde of
|
||||
PageTablePDE ref _ _ \<Rightarrow> return $ ptrFromPAddr ref
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ (show pd) @ [] @ (show pde)
|
||||
);
|
||||
offset \<leftarrow> return ( fromVPtr $ ((vptr &&(mask $ pageBitsForSize ARMSection))
|
||||
`~shiftR~` pageBitsForSize ARMSmallPage));
|
||||
targetSlot \<leftarrow> return ( pt + (PPtr $ offset `~shiftL~` 2));
|
||||
pte \<leftarrow> return ( SmallPagePTE_ \<lparr>
|
||||
pteFrame= addrFromPPtr frame,
|
||||
pteCacheable= True,
|
||||
pteGlobal= False,
|
||||
pteExecuteNever= False,
|
||||
pteRights= VMReadWrite \<rparr>);
|
||||
storePTE targetSlot pte
|
||||
od)"
|
||||
|
||||
defs createIPCBufferFrame_def:
|
||||
"createIPCBufferFrame rootCNCap vptr\<equiv> (do
|
||||
pptr \<leftarrow> allocFrame;
|
||||
doKernelOp $ doMachineOp $ clearMemory (ptrFromPAddr pptr) (1 `~shiftL~` pageBits);
|
||||
cap \<leftarrow> createITFrameCap (ptrFromPAddr pptr) vptr (Just itASID) False;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapITIPCBuf;
|
||||
doKernelOp $ insertInitCap slot cap;
|
||||
bootInfo \<leftarrow> noInitFailure $ gets (initBootInfo);
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifIPCBufVPtr := vptr\<rparr>);
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr>initBootInfo := bootInfo' \<rparr>);
|
||||
return cap
|
||||
od)"
|
||||
|
||||
defs createBIFrame_def:
|
||||
"createBIFrame rootCNCap vptr nodeId numNodes\<equiv> (do
|
||||
pptr \<leftarrow> allocFrame;
|
||||
bootInfo \<leftarrow> noInitFailure $ gets initBootInfo;
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifNodeID := nodeId,
|
||||
bifNumNodes := numNodes \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr>
|
||||
initBootInfo := bootInfo',
|
||||
initBootInfoFrame := pptr,
|
||||
initSlotPosCur := biCapDynStart
|
||||
\<rparr>);
|
||||
doKernelOp $ doMachineOp $ clearMemory (ptrFromPAddr pptr) (1 `~shiftL~` pageBits);
|
||||
cap \<leftarrow> createITFrameCap (ptrFromPAddr pptr) vptr (Just itASID) False;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapBIFrame;
|
||||
doKernelOp $ insertInitCap slot cap;
|
||||
return cap
|
||||
od)"
|
||||
|
||||
defs createITFrameCap_def:
|
||||
"createITFrameCap pptr vptr asid large\<equiv> (do
|
||||
sz \<leftarrow> return ( if large then ARMLargePage else ARMSmallPage);
|
||||
addr \<leftarrow> return ( (case asid of
|
||||
Some asid' \<Rightarrow> Just (asid', vptr)
|
||||
| None \<Rightarrow> Nothing
|
||||
));
|
||||
frame \<leftarrow> return ( PageCap_ \<lparr>
|
||||
capVPBasePtr= pptr,
|
||||
capVPRights= VMReadWrite,
|
||||
capVPSize= sz,
|
||||
capVPMappedAddress= addr \<rparr>);
|
||||
return $ ArchObjectCap $ frame
|
||||
od)"
|
||||
|
||||
defs createFramesOfRegion_def:
|
||||
"createFramesOfRegion rootCNCap region doMap pvOffset\<equiv> (do
|
||||
curSlotPos \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
(startPPtr, endPPtr) \<leftarrow> return $ fromRegion region;
|
||||
forM_x [startPPtr,startPPtr + (bit pageBits) .e. endPPtr] (\<lambda> ptr. (do
|
||||
paddr \<leftarrow> return ( fromPAddr $ addrFromPPtr ptr);
|
||||
frameCap \<leftarrow> if doMap then
|
||||
createITFrameCap ptr ((VPtr paddr) + pvOffset ) (Just itASID) False
|
||||
else createITFrameCap ptr 0 Nothing False;
|
||||
provideCap rootCNCap frameCap
|
||||
od));
|
||||
slotPosAfter \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
bootInfo \<leftarrow> noInitFailure $ gets initBootInfo;
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifUIFrameCaps := [curSlotPos .e. slotPosAfter - 1] \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr> initBootInfo := bootInfo' \<rparr>)
|
||||
od)"
|
||||
|
||||
defs mapGlobalsFrame_def:
|
||||
"mapGlobalsFrame\<equiv> (do
|
||||
globalsFrame \<leftarrow> gets $ armKSGlobalsFrame \<circ> ksArchState;
|
||||
mapKernelFrame (addrFromPPtr globalsFrame) globalsBase VMReadOnly $
|
||||
VMAttributes True True False
|
||||
VMAttributes True True True;
|
||||
writeIdleCode
|
||||
od)"
|
||||
|
||||
defs createInitialRoot_def:
|
||||
"createInitialRoot slot\<equiv> (do
|
||||
asid \<leftarrow> return ( 1);
|
||||
initPDFrame \<leftarrow> allocRegion pdBits;
|
||||
initPD \<leftarrow> return ( ptrFromPAddr initPDFrame);
|
||||
rootCap \<leftarrow> return ( ArchObjectCap $ PageDirectoryCap_ \<lparr>
|
||||
capPDBasePtr= initPD,
|
||||
capPDMappedASID= Just asid \<rparr>);
|
||||
doKernelOp $ (do
|
||||
placeNewObject (ptrFromPAddr initPDFrame) (makeObject ::pde)
|
||||
(pdBits `~shiftR~` (objBits (makeObject ::pde)));
|
||||
copyGlobalMappings initPD;
|
||||
insertInitCap slot rootCap
|
||||
od);
|
||||
initASIDPoolFrame \<leftarrow> allocRegion $ objBits (undefined ::asidpool);
|
||||
initASIDPoolPtr \<leftarrow> return ( ptrFromPAddr initASIDPoolFrame);
|
||||
emptyASIDPool \<leftarrow> liftM (inv ASIDPool) $ return ( (makeObject ::asidpool));
|
||||
initASIDPool \<leftarrow> return ( ASIDPool $ emptyASIDPool aLU [(asid && mask asidLowBits, Just initPD)]);
|
||||
doKernelOp $ (do
|
||||
placeNewObject (ptrFromPAddr initASIDPoolFrame) initASIDPool 0;
|
||||
asidTable \<leftarrow> gets (armKSASIDTable \<circ> ksArchState);
|
||||
asidTable' \<leftarrow> return (
|
||||
asidTable aLU [(asidHighBitsOf asid, Just initASIDPoolPtr)]);
|
||||
modify (\<lambda> s. s \<lparr>
|
||||
ksArchState := (ksArchState s) \<lparr> armKSASIDTable := asidTable' \<rparr>\<rparr>)
|
||||
od);
|
||||
provideCap $ ArchObjectCap $ ASIDControlCap;
|
||||
provideCap $ ArchObjectCap $ ASIDPoolCap_ \<lparr>
|
||||
capASIDPool= initASIDPoolPtr,
|
||||
capASIDBase= 0 \<rparr>;
|
||||
return rootCap
|
||||
defs writeIdleCode_def:
|
||||
"writeIdleCode\<equiv> (do
|
||||
globalsFrame \<leftarrow> gets $ armKSGlobalsFrame \<circ> ksArchState;
|
||||
offset \<leftarrow> return ( fromVPtr $ idleThreadStart - globalsBase);
|
||||
doMachineOp $ mapM_x
|
||||
(split storeWord
|
||||
)
|
||||
(zipE2 (globalsFrame + PPtr offset) ( globalsFrame + PPtr offset + 4) (idleThreadCode))
|
||||
od)"
|
||||
|
||||
defs populateInitialRoot_def:
|
||||
"populateInitialRoot vRoot cRoot\<equiv> (do
|
||||
asid \<leftarrow> return ( fromJust $ capPDMappedASID $ capCap vRoot);
|
||||
pdCap \<leftarrow> liftM capCap $ return ( vRoot);
|
||||
pd \<leftarrow> return ( capPDBasePtr pdCap);
|
||||
(case cRoot of
|
||||
CNodeCap _ _ _ _ \<Rightarrow> return ()
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
haskell_assert (capCNodeGuard cRoot = 0) $
|
||||
[];
|
||||
haskell_assert (capCNodeBits cRoot + capCNodeGuardSize cRoot + pageBits =
|
||||
finiteBitSize (undefined::machine_word)) $
|
||||
[];
|
||||
forM_x [0 .e. 1 `~shiftL~` capCNodeBits cRoot - 1] (\<lambda> index. (do
|
||||
cSlot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr cRoot) index;
|
||||
cte \<leftarrow> doKernelOp $ getObject cSlot;
|
||||
(let v2 = cteCap cte in
|
||||
if isArchObjectCap v2 \<and> isPageCap (capCap v2)
|
||||
then
|
||||
let pageCap = capCap v2
|
||||
in (do
|
||||
haskell_assert (capVPSize pageCap = ARMSmallPage) $
|
||||
[];
|
||||
vaddr \<leftarrow> return ( VPtr $ index `~shiftL~` pageBits);
|
||||
pageCap' \<leftarrow> return ( pageCap \<lparr>
|
||||
capVPMappedAddress := Just (asid, vaddr) \<rparr>);
|
||||
cte' \<leftarrow> return ( cte \<lparr> cteCap := ArchObjectCap pageCap' \<rparr>);
|
||||
doKernelOp $ setObject cSlot cte';
|
||||
mapUserFrame pd asid
|
||||
(addrFromPPtr $ capVPBasePtr pageCap) vaddr
|
||||
od)
|
||||
else return ()
|
||||
)
|
||||
od))
|
||||
defs mapKernelFrame_def:
|
||||
"mapKernelFrame paddr vaddr vmrights attributes\<equiv> (do
|
||||
idx \<leftarrow> return ( fromVPtr $ ( (vaddr && (mask $ pageBitsForSize ARMSection))
|
||||
`~shiftR~` pageBitsForSize ARMSmallPage));
|
||||
globalPT \<leftarrow> getARMGlobalPT;
|
||||
pte \<leftarrow> return ( SmallPagePTE_ \<lparr>
|
||||
pteFrame= paddr,
|
||||
pteCacheable= armPageCacheable attributes,
|
||||
pteGlobal= True,
|
||||
pteExecuteNever= False,
|
||||
pteRights= vmrights \<rparr>);
|
||||
storePTE (PPtr ((fromPPtr globalPT) + (idx `~shiftL~` 2))) pte
|
||||
od)"
|
||||
|
||||
defs allocUserPT_def:
|
||||
"allocUserPT asid vaddr\<equiv> (do
|
||||
initPTFrame \<leftarrow> allocRegion ptBits;
|
||||
doKernelOp $ placeNewObject (ptrFromPAddr initPTFrame)
|
||||
(makeObject ::pte) (ptBits `~shiftR~` (objBits (makeObject ::pte)));
|
||||
initPT \<leftarrow> return ( ptrFromPAddr initPTFrame);
|
||||
provideCap $ ArchObjectCap $ PageTableCap_ \<lparr>
|
||||
capPTBasePtr= initPT,
|
||||
capPTMappedAddress= Just (asid, vaddr) \<rparr>;
|
||||
return initPT
|
||||
defs getARMGlobalPT_def:
|
||||
"getARMGlobalPT\<equiv> (do
|
||||
pt \<leftarrow> gets (head \<circ> armKSGlobalPTs \<circ> ksArchState);
|
||||
return pt
|
||||
od)"
|
||||
|
||||
defs mapUserFrame_def:
|
||||
"mapUserFrame pd asid paddr vptr\<equiv> (do
|
||||
haskell_assert (vptr < kernelBase) [];
|
||||
pdSlot \<leftarrow> return ( lookupPDSlot pd vptr);
|
||||
pde \<leftarrow> doKernelOp $ getObject pdSlot;
|
||||
pteBits \<leftarrow> return ( objBits (undefined ::pte));
|
||||
ptIndex \<leftarrow> return ( fromVPtr $ vptr `~shiftR~` 12 && 0xff);
|
||||
ptSlot \<leftarrow> (case pde of
|
||||
PageTablePDE _ _ _ \<Rightarrow> (do
|
||||
pt \<leftarrow> return ( ptrFromPAddr $ pdeTable pde);
|
||||
return $ pt + (PPtr $ ptIndex `~shiftL~` pteBits)
|
||||
od)
|
||||
| InvalidPDE \<Rightarrow> (do
|
||||
ptFrame \<leftarrow> allocUserPT asid vptr;
|
||||
pde \<leftarrow> return ( PageTablePDE_ \<lparr>
|
||||
pdeTable= addrFromPPtr ptFrame,
|
||||
pdeParity= True,
|
||||
pdeDomain= 0 \<rparr>);
|
||||
doKernelOp $ storePDE pdSlot pde;
|
||||
return $ PPtr $ fromPPtr ptFrame + (ptIndex `~shiftL~` pteBits)
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
);
|
||||
doKernelOp $ (do
|
||||
pte \<leftarrow> getObject ptSlot;
|
||||
(case pte of
|
||||
InvalidPTE \<Rightarrow> (do
|
||||
pte' \<leftarrow> return ( SmallPagePTE_ \<lparr>
|
||||
pteFrame= paddr,
|
||||
pteCacheable= True,
|
||||
pteGlobal= False,
|
||||
pteExecuteNever= False,
|
||||
pteRights= VMReadWrite \<rparr>);
|
||||
storePTE ptSlot pte'
|
||||
defs createDeviceFrames_def:
|
||||
"createDeviceFrames rootCNodeCap\<equiv> (do
|
||||
deviceRegions \<leftarrow> doKernelOp $ doMachineOp getDeviceRegions;
|
||||
(flip mapM_x) deviceRegions (\<lambda> (start,end). (do
|
||||
frameSize \<leftarrow> return $ if (isAligned start (pageBitsForSize ARMSection))
|
||||
\<and> isAligned end (pageBitsForSize ARMSection)
|
||||
then ARMSection else ARMSmallPage;
|
||||
slotBefore \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
(flip mapM_x) [start, (start + (bit (pageBitsForSize frameSize))) .e. (end - 1)]
|
||||
(\<lambda> f. (do
|
||||
frameCap \<leftarrow> createITFrameCap (ptrFromPAddr f) 0 Nothing (frameSize = ARMSection);
|
||||
provideCap rootCNodeCap frameCap
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
);
|
||||
slotAfter \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
biDeviceRegion \<leftarrow> return ( BIDeviceRegion_ \<lparr>
|
||||
bidrBasePAddr= start,
|
||||
bidrFrameSizeBits= fromIntegral $ pageBitsForSize frameSize,
|
||||
bidrFrameCaps= SlotRegion (slotBefore, slotAfter) \<rparr>);
|
||||
devRegions \<leftarrow> noInitFailure $ gets (bifDeviceRegions \<circ> initBootInfo);
|
||||
devRegions' \<leftarrow> return ( devRegions @ [biDeviceRegion]);
|
||||
bootInfo \<leftarrow> noInitFailure $ gets (initBootInfo);
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifDeviceRegions := devRegions' \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initBootInfo := bootInfo' \<rparr>)
|
||||
od)
|
||||
);
|
||||
bInfo \<leftarrow> noInitFailure $ gets (initBootInfo);
|
||||
bInfo' \<leftarrow> return ( bInfo \<lparr> bifNumDeviceRegions := (fromIntegral \<circ> length \<circ> bifDeviceRegions) bInfo \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initBootInfo := bInfo' \<rparr>)
|
||||
od)"
|
||||
|
||||
defs copyGlobalMappings_def:
|
||||
|
@ -426,9 +494,9 @@ defs lookupIPCBuffer_def:
|
|||
bufferPtr \<leftarrow> threadGet tcbIPCBuffer thread;
|
||||
bufferFrameSlot \<leftarrow> getThreadBufferSlot thread;
|
||||
bufferCap \<leftarrow> getSlotCap bufferFrameSlot;
|
||||
(let v4 = bufferCap in
|
||||
if isArchObjectCap v4 \<and> isPageCap (capCap v4)
|
||||
then let frame = capCap v4
|
||||
(let v3 = bufferCap in
|
||||
if isArchObjectCap v3 \<and> isPageCap (capCap v3)
|
||||
then let frame = capCap v3
|
||||
in (do
|
||||
rights \<leftarrow> return ( capVPRights frame);
|
||||
pBits \<leftarrow> return ( pageBitsForSize $ capVPSize frame);
|
||||
|
@ -699,9 +767,9 @@ defs setVMRoot_def:
|
|||
| _ \<Rightarrow> return ()
|
||||
);
|
||||
globalPD \<leftarrow> gets (armKSGlobalPD \<circ> ksArchState);
|
||||
doMachineOp $ setCurrentPD $ addrFromPPtr globalPD
|
||||
doMachineOp $ setCurrentPD $ addrFromPPtr globalPD
|
||||
od)
|
||||
)
|
||||
)
|
||||
od)"
|
||||
|
||||
defs setVMRootForFlush_def:
|
||||
|
@ -709,8 +777,8 @@ defs setVMRootForFlush_def:
|
|||
tcb \<leftarrow> getCurThread;
|
||||
threadRootSlot \<leftarrow> getThreadVSpaceRoot tcb;
|
||||
threadRoot \<leftarrow> getSlotCap threadRootSlot;
|
||||
(let v8 = threadRoot in
|
||||
if isArchObjectCap v8 \<and> isPageDirectoryCap (capCap v8) \<and> capPDMappedASID (capCap v8) \<noteq> None \<and> capPDBasePtr (capCap v8) = pd
|
||||
(let v7 = threadRoot in
|
||||
if isArchObjectCap v7 \<and> isPageDirectoryCap (capCap v7) \<and> capPDMappedASID (capCap v7) \<noteq> None \<and> capPDBasePtr (capCap v7) = pd
|
||||
then let cur_pd = pd in return False
|
||||
else (do
|
||||
armv_contextSwitch pd asid;
|
||||
|
@ -734,28 +802,6 @@ defs checkValidIPCBuffer_def:
|
|||
| _ \<Rightarrow> throw IllegalOperation
|
||||
)"
|
||||
|
||||
defs createInitPage_def:
|
||||
"createInitPage addr\<equiv> (do
|
||||
ptr \<leftarrow> return ( ptrFromPAddr addr);
|
||||
reserveFrame ptr False;
|
||||
return $ ArchObjectCap $ PageCap ptr VMReadWrite ARMSmallPage Nothing
|
||||
od)"
|
||||
|
||||
defs createDeviceCap_def:
|
||||
"createDeviceCap x0\<equiv> (case x0 of
|
||||
(addr, end) \<Rightarrow> (do
|
||||
wptr \<leftarrow> return ( ptrFromPAddr addr);
|
||||
rawmagnitude \<leftarrow> return ( end - addr);
|
||||
sz \<leftarrow> return ( find (\<lambda> sz. rawmagnitude = bit (pageBitsForSize sz))
|
||||
[minBound .e. maxBound]);
|
||||
magnitude \<leftarrow> (case sz of
|
||||
Some magnitude \<Rightarrow> return magnitude
|
||||
| None \<Rightarrow> haskell_fail []
|
||||
);
|
||||
return $ ArchObjectCap $ PageCap wptr VMReadWrite magnitude Nothing
|
||||
od)
|
||||
)"
|
||||
|
||||
defs maskVMRights_def:
|
||||
"maskVMRights r m\<equiv> (case (r, capAllowRead m, capAllowWrite m) of
|
||||
(VMNoAccess, _, _) \<Rightarrow> VMNoAccess
|
||||
|
@ -957,15 +1003,15 @@ defs resolveVAddr_def:
|
|||
pdSlot \<leftarrow> return ( lookupPDSlot pd vaddr);
|
||||
pde \<leftarrow> getObject pdSlot;
|
||||
(case pde of
|
||||
SectionPDE frame v18 v19 v20 v21 v22 v23 \<Rightarrow> return $ Just (ARMSection, frame)
|
||||
| SuperSectionPDE frame v24 v25 v26 v27 v28 \<Rightarrow> return $ Just (ARMSuperSection, frame)
|
||||
| PageTablePDE table v29 v30 \<Rightarrow> (do
|
||||
SectionPDE frame v17 v18 v19 v20 v21 v22 \<Rightarrow> return $ Just (ARMSection, frame)
|
||||
| SuperSectionPDE frame v23 v24 v25 v26 v27 \<Rightarrow> return $ Just (ARMSuperSection, frame)
|
||||
| PageTablePDE table v28 v29 \<Rightarrow> (do
|
||||
pt \<leftarrow> return ( ptrFromPAddr table);
|
||||
pteSlot \<leftarrow> return ( lookupPTSlot_nofail pt vaddr);
|
||||
pte \<leftarrow> getObject pteSlot;
|
||||
(case pte of
|
||||
LargePagePTE frame v10 v11 v12 v13 \<Rightarrow> return $ Just (ARMLargePage, frame)
|
||||
| SmallPagePTE frame v14 v15 v16 v17 \<Rightarrow> return $ Just (ARMSmallPage, frame)
|
||||
LargePagePTE frame v9 v10 v11 v12 \<Rightarrow> return $ Just (ARMLargePage, frame)
|
||||
| SmallPagePTE frame v13 v14 v15 v16 \<Rightarrow> return $ Just (ARMSmallPage, frame)
|
||||
| _ \<Rightarrow> return Nothing
|
||||
)
|
||||
od)
|
||||
|
@ -1126,8 +1172,8 @@ defs decodeARMMMUInvocation_def:
|
|||
whenE (null free) $ throw DeleteFirst;
|
||||
base \<leftarrow> returnOk ( (fst $ head free) `~shiftL~` asidLowBits);
|
||||
pool \<leftarrow> returnOk ( makeObject ::asidpool);
|
||||
frame \<leftarrow> (let v31 = untyped in
|
||||
if isUntypedCap v31 \<and> capBlockSize v31 = objBits pool
|
||||
frame \<leftarrow> (let v30 = untyped in
|
||||
if isUntypedCap v30 \<and> capBlockSize v30 = objBits pool
|
||||
then (doE
|
||||
ensureNoChildren parentSlot;
|
||||
returnOk $ capPtr untyped
|
||||
|
|
|
@ -25,7 +25,7 @@ where
|
|||
definition
|
||||
rootCNodeSize :: "nat"
|
||||
where
|
||||
"rootCNodeSize \<equiv> 8"
|
||||
"rootCNodeSize \<equiv> 12"
|
||||
|
||||
definition
|
||||
timeSlice :: "nat"
|
||||
|
|
|
@ -261,6 +261,9 @@ where
|
|||
UnknownSyscallException v0 \<Rightarrow> True
|
||||
| _ \<Rightarrow> False"
|
||||
|
||||
datatype init_failure =
|
||||
InitFailure
|
||||
|
||||
datatype syscall_error =
|
||||
IllegalOperation
|
||||
| InvalidArgument nat
|
||||
|
|
|
@ -36,7 +36,7 @@ consts
|
|||
deletingIRQHandler :: "irq \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
initInterruptController :: "capability kernel_init"
|
||||
initInterruptController :: "capability \<Rightarrow> machine_word \<Rightarrow> capability kernel_init"
|
||||
|
||||
consts
|
||||
handleInterrupt :: "irq \<Rightarrow> unit kernel"
|
||||
|
@ -133,19 +133,21 @@ defs deletedIRQHandler_def:
|
|||
setIRQState IRQInactive irq"
|
||||
|
||||
defs initInterruptController_def:
|
||||
"initInterruptController\<equiv> (do
|
||||
"initInterruptController rootCNCap biCapIRQC\<equiv> (do
|
||||
frame \<leftarrow> allocFrame;
|
||||
doKernelOp $ (do
|
||||
haskell_assert (length [minBound .e. (maxBound::irq)]
|
||||
`~shiftL~` (objBits (makeObject ::cte)) \<le> bit pageBits)
|
||||
[];
|
||||
placeNewObject (ptrFromPAddr frame) (makeObject ::cte)
|
||||
(bit pageBits `~shiftR~` objBits (makeObject ::cte));
|
||||
(pageBits - objBits (makeObject ::cte));
|
||||
doMachineOp $ mapM_x (maskInterrupt True) [minBound .e. maxBound];
|
||||
irqTable \<leftarrow> return ( funArray $ const IRQInactive);
|
||||
setInterruptState $ InterruptState (ptrFromPAddr frame) irqTable;
|
||||
timerIRQ \<leftarrow> doMachineOp configureTimer;
|
||||
setIRQState IRQTimer timerIRQ
|
||||
setIRQState IRQTimer timerIRQ;
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapIRQC;
|
||||
insertInitCap slot IRQControlCap
|
||||
od);
|
||||
return IRQControlCap
|
||||
od)"
|
||||
|
|
|
@ -16,86 +16,56 @@ imports
|
|||
KernelInitMonad_H
|
||||
begin
|
||||
|
||||
consts
|
||||
noInitFailure :: "'a kernel_init_state \<Rightarrow> 'a kernel_init"
|
||||
|
||||
consts
|
||||
minNum4kUntypedObj :: "nat"
|
||||
|
||||
consts
|
||||
maxNumFreememRegions :: "nat"
|
||||
|
||||
consts
|
||||
getAPRegion :: "paddr \<Rightarrow> region list kernel_init"
|
||||
|
||||
consts
|
||||
initFreemem :: "paddr \<Rightarrow> region \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
allocRegion :: "nat \<Rightarrow> paddr kernel_init"
|
||||
|
||||
consts
|
||||
allocFrame :: "paddr kernel_init"
|
||||
|
||||
consts
|
||||
allocPage :: "(vptr * machine_word * machine_word) kernel_init"
|
||||
|
||||
consts
|
||||
mapForInitTask :: "paddr \<Rightarrow> vptr \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
makeRootCNode :: "capability kernel_init"
|
||||
|
||||
consts
|
||||
allocRootSlot :: "(cptr * machine_word) kernel_init"
|
||||
|
||||
consts
|
||||
allocRootSlotWithColour :: "machine_word \<Rightarrow> (cptr * machine_word) kernel_init"
|
||||
|
||||
consts
|
||||
requestRootSlot :: "cptr \<Rightarrow> (machine_word) kernel_init"
|
||||
|
||||
consts
|
||||
makeSlots :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
provideCap :: "capability \<Rightarrow> (cptr * machine_word) kernel_init"
|
||||
|
||||
consts
|
||||
provideRegion :: "boot_region \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
mergeBRs :: "boot_region \<Rightarrow> boot_region \<Rightarrow> nat \<Rightarrow> boot_region option"
|
||||
|
||||
consts
|
||||
addRegionWithMerge :: "boot_region \<Rightarrow> nat \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
initKernel :: "vptr \<Rightarrow> paddr list \<Rightarrow> vptr \<Rightarrow> paddr list \<Rightarrow> paddr list \<Rightarrow> unit kernel"
|
||||
|
||||
consts
|
||||
finaliseBIFrame :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
createInitialThread :: "capability \<Rightarrow> capability \<Rightarrow> capability \<Rightarrow> vptr \<Rightarrow> vptr \<Rightarrow> vptr \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
createIdleThread :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
createUntypedObject :: "capability \<Rightarrow> region \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
mapTaskRegions :: "(paddr * vptr) list \<Rightarrow> ((vptr * machine_word) * (vptr * machine_word)) kernel_init"
|
||||
|
||||
consts
|
||||
createInitCaps :: "capability \<Rightarrow> (vptr * machine_word) \<Rightarrow> capability kernel_init"
|
||||
allocFrame :: "paddr kernel_init"
|
||||
|
||||
consts
|
||||
createUntypedCaps :: "unit kernel_init"
|
||||
makeRootCNode :: "capability kernel_init"
|
||||
|
||||
consts
|
||||
storeLargeBlock :: "(paddr * nat) \<Rightarrow> unit kernel_init"
|
||||
provideCap :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
makeBlockList :: "paddr \<Rightarrow> paddr \<Rightarrow> (paddr * nat) list"
|
||||
provideUntypedCap :: "capability \<Rightarrow> paddr \<Rightarrow> word8 \<Rightarrow> machine_word \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
countUntypedCaps :: "nat kernel_init"
|
||||
|
||||
consts
|
||||
getUntypedRegions :: "(paddr * paddr) list kernel_init"
|
||||
|
||||
consts
|
||||
createDeviceCaps :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
createSmallBlockCaps :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
storeSmallBlockCaps :: "capability list \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
storeSmallBlockCap :: "capability \<Rightarrow> unit kernel_init"
|
||||
|
||||
consts
|
||||
createFreeSlotRegions :: "unit kernel_init"
|
||||
|
||||
consts
|
||||
createEmptyRegions :: "unit kernel_init"
|
||||
coverOf :: "region list \<Rightarrow> region"
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -18,466 +18,273 @@ imports
|
|||
Config_H
|
||||
begin
|
||||
|
||||
defs noInitFailure_def:
|
||||
"noInitFailure \<equiv> lift"
|
||||
|
||||
defs minNum4kUntypedObj_def:
|
||||
"minNum4kUntypedObj \<equiv> 12"
|
||||
|
||||
defs maxNumFreememRegions_def:
|
||||
"maxNumFreememRegions \<equiv> 2"
|
||||
|
||||
defs getAPRegion_def:
|
||||
"getAPRegion kernelFrameEnd\<equiv> (do
|
||||
memRegions \<leftarrow> doKernelOp $ doMachineOp getMemoryRegions;
|
||||
subRegions \<leftarrow> return $ (flip map) memRegions (\<lambda> x.
|
||||
let (s,e) = x in
|
||||
if s < kernelFrameEnd then (kernelFrameEnd,e) else (s,e)
|
||||
);
|
||||
return $ map ptrFromPAddrRegion subRegions
|
||||
od)"
|
||||
|
||||
defs initFreemem_def:
|
||||
"initFreemem kernelFrameEnd uiRegion\<equiv> (do
|
||||
memRegions \<leftarrow> getAPRegion kernelFrameEnd;
|
||||
region \<leftarrow> return ( fromRegion uiRegion);
|
||||
fst' \<leftarrow> return ( fst \<circ> fromRegion);
|
||||
snd' \<leftarrow> return ( snd \<circ> fromRegion);
|
||||
subUI \<leftarrow> return ( \<lambda> r.
|
||||
if fst region \<ge> fst' r \<and> snd region \<le> snd' r
|
||||
then [(fst' r, fst region), (snd region, snd' r)]
|
||||
else [(fst' r, snd' r)]);
|
||||
freeRegions \<leftarrow> return ( concat $ map subUI memRegions);
|
||||
freeRegions' \<leftarrow> return ( take maxNumFreememRegions $ freeRegions @
|
||||
(if (length freeRegions < maxNumFreememRegions)
|
||||
then replicate (maxNumFreememRegions - length freeRegions) (PPtr 0, PPtr 0)
|
||||
else []));
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initFreeMemory := map Region freeRegions' \<rparr>)
|
||||
od)"
|
||||
|
||||
defs allocRegion_def:
|
||||
"allocRegion bits \<equiv>
|
||||
let
|
||||
s = 1 `~shiftL~` bits;
|
||||
align = (\<lambda> b. (((b - 1) `~shiftR~` bits) + 1) `~shiftL~` bits);
|
||||
isUsable = (\<lambda> (b, t). let r = align b in r \<ge> b \<and> r + s - 1 \<le> t)
|
||||
isUsable = (\<lambda> reg. let r = (align \<circ> fst \<circ> fromRegion) reg in
|
||||
r \<ge> (fst $ fromRegion reg) \<and> r + s - 1 \<le> (snd $ fromRegion reg));
|
||||
isAlignedUsable = (\<lambda> reg.
|
||||
let
|
||||
b = fst $ fromRegion reg;
|
||||
t = snd $ fromRegion reg;
|
||||
(r, q) = (align b, align t)
|
||||
in (r = b \<or> q = t) \<and> t - b \<ge> s)
|
||||
in
|
||||
(do
|
||||
freeMem \<leftarrow> gets initFreeMemory;
|
||||
(case isUsable `~break~` freeMem of
|
||||
(small, (b, t)#rest) \<Rightarrow> (do
|
||||
result \<leftarrow> return ( align b);
|
||||
below \<leftarrow> return ( if result = b then [] else [(b, result - 1)]);
|
||||
above \<leftarrow> return ( if result + s - 1 = t then [] else [(result + s, t)]);
|
||||
modify (\<lambda> st. st \<lparr> initFreeMemory := small@below@above@rest \<rparr>);
|
||||
return result
|
||||
freeMem \<leftarrow> noInitFailure $ gets initFreeMemory;
|
||||
(case isAlignedUsable `~break~` freeMem of
|
||||
(small, r#rest) \<Rightarrow> (do
|
||||
(b, t) \<leftarrow> return ( fromRegion r);
|
||||
(result, region) \<leftarrow> return ( if align b = b then (b, Region (b + s, t)) else (t - s, Region (b, t - s)));
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initFreeMemory := small@ [region] @rest \<rparr>);
|
||||
return $ addrFromPPtr result
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
| (_, []) \<Rightarrow>
|
||||
(case isUsable `~break~` freeMem of
|
||||
(small, r'#rest) \<Rightarrow> (do
|
||||
(b, t) \<leftarrow> return ( fromRegion r');
|
||||
result \<leftarrow> return ( align b);
|
||||
below \<leftarrow> return ( if result = b then [] else [Region (b, result)]);
|
||||
above \<leftarrow> return ( if result + s = t then [] else [Region (result + s, t)]);
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initFreeMemory := small@below@above@rest \<rparr>);
|
||||
return $ addrFromPPtr result
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
)
|
||||
od)"
|
||||
|
||||
defs initKernel_def:
|
||||
"initKernel entry initFrames initOffset kernelFrames bootFrames\<equiv> (do
|
||||
wordSize \<leftarrow> return ( finiteBitSize entry);
|
||||
uiRegion \<leftarrow> return ( coverOf $ map (\<lambda> x. Region (ptrFromPAddr x, (ptrFromPAddr x) + bit (pageBits))) initFrames);
|
||||
kernelRegion \<leftarrow> return ( coverOf $ map (\<lambda> x. Region (ptrFromPAddr x, (ptrFromPAddr x) + bit (pageBits))) kernelFrames);
|
||||
kePPtr \<leftarrow> return ( fst $ fromRegion $ uiRegion);
|
||||
kfEndPAddr \<leftarrow> return ( addrFromPPtr kePPtr);
|
||||
(startPPtr,endPPtr) \<leftarrow> return $ fromRegion uiRegion;
|
||||
vptrStart \<leftarrow> return ( (VPtr (fromPAddr $ addrFromPPtr $ startPPtr )) + initOffset);
|
||||
vptrEnd \<leftarrow> return ( (VPtr (fromPAddr $ addrFromPPtr $ endPPtr )) + initOffset);
|
||||
allMemory \<leftarrow> doMachineOp getMemoryRegions;
|
||||
initPSpace $ map (\<lambda> (s, e). (ptrFromPAddr s, ptrFromPAddr e))
|
||||
allMemory;
|
||||
mapM (\<lambda> p. reserveFrame (ptrFromPAddr p) True) $ kernelFrames @ bootFrames;
|
||||
initKernelVM;
|
||||
initCPU;
|
||||
initPlatform;
|
||||
runInit $ (do
|
||||
initFreemem kfEndPAddr uiRegion;
|
||||
rootCNCap \<leftarrow> makeRootCNode;
|
||||
initInterruptController rootCNCap biCapIRQControl;
|
||||
ipcBufferVPtr \<leftarrow> return ( vptrEnd);
|
||||
ipcBufferCap \<leftarrow> createIPCBufferFrame rootCNCap ipcBufferVPtr;
|
||||
biFrameVPtr \<leftarrow> return ( vptrEnd + (1 `~shiftL~` pageBits));
|
||||
createBIFrame rootCNCap biFrameVPtr 0 1;
|
||||
createFramesOfRegion rootCNCap uiRegion True initOffset;
|
||||
itPDCap \<leftarrow> createITPDPTs rootCNCap vptrStart biFrameVPtr;
|
||||
writeITPDPTs rootCNCap itPDCap;
|
||||
itAPCap \<leftarrow> createITASIDPool rootCNCap;
|
||||
doKernelOp $ writeITASIDPool itAPCap itPDCap;
|
||||
createIdleThread;
|
||||
createInitialThread rootCNCap itPDCap ipcBufferCap entry ipcBufferVPtr biFrameVPtr;
|
||||
createUntypedObject rootCNCap (Region (0,0));
|
||||
createDeviceFrames rootCNCap;
|
||||
finaliseBIFrame;
|
||||
syncBIFrame
|
||||
od)
|
||||
od)"
|
||||
|
||||
defs finaliseBIFrame_def:
|
||||
"finaliseBIFrame\<equiv> (do
|
||||
cur \<leftarrow> noInitFailure $ gets $ initSlotPosCur;
|
||||
max \<leftarrow> noInitFailure $ gets $ initSlotPosMax;
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr> initBootInfo := (initBootInfo s) \<lparr>bifNullCaps := [cur .e. max - 1]\<rparr>\<rparr>)
|
||||
od)"
|
||||
|
||||
defs createInitialThread_def:
|
||||
"createInitialThread rootCNCap itPDCap ipcBufferCap entry ipcBufferVPtr biFrameVPtr\<equiv> (do
|
||||
tcbBits \<leftarrow> return ( objBits (makeObject::tcb));
|
||||
tcb' \<leftarrow> allocRegion tcbBits;
|
||||
tcbPPtr \<leftarrow> return ( ptrFromPAddr tcb');
|
||||
doKernelOp $ (do
|
||||
placeNewObject tcbPPtr (makeObject::tcb) 0;
|
||||
srcSlot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapITCNode;
|
||||
destSlot \<leftarrow> getThreadCSpaceRoot tcbPPtr;
|
||||
cteInsert rootCNCap srcSlot destSlot;
|
||||
srcSlot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapITPD;
|
||||
destSlot \<leftarrow> getThreadVSpaceRoot tcbPPtr;
|
||||
cteInsert itPDCap srcSlot destSlot;
|
||||
srcSlot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapITIPCBuf;
|
||||
destSlot \<leftarrow> getThreadBufferSlot tcbPPtr;
|
||||
cteInsert ipcBufferCap srcSlot destSlot;
|
||||
threadSet (\<lambda> t. t\<lparr>tcbIPCBuffer := ipcBufferVPtr\<rparr>) tcbPPtr;
|
||||
activateInitialThread tcbPPtr entry biFrameVPtr;
|
||||
cap \<leftarrow> return $ ThreadCap tcbPPtr;
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap) biCapITTCB;
|
||||
insertInitCap slot cap
|
||||
od);
|
||||
return ()
|
||||
od)"
|
||||
|
||||
defs createIdleThread_def:
|
||||
"createIdleThread\<equiv> (do
|
||||
paddr \<leftarrow> allocRegion $ objBits (makeObject ::tcb);
|
||||
tcbPPtr \<leftarrow> return ( ptrFromPAddr paddr);
|
||||
doKernelOp $ (do
|
||||
placeNewObject tcbPPtr (makeObject::tcb) 0;
|
||||
modify (\<lambda> s. s \<lparr>ksIdleThread := tcbPPtr\<rparr>);
|
||||
setCurThread tcbPPtr;
|
||||
setSchedulerAction ResumeCurrentThread
|
||||
od);
|
||||
configureIdleThread tcbPPtr
|
||||
od)"
|
||||
|
||||
defs createUntypedObject_def:
|
||||
"createUntypedObject rootCNodeCap bootMemReuseReg\<equiv> (do
|
||||
regStart \<leftarrow> return ( (fst \<circ> fromRegion));
|
||||
regStartPAddr \<leftarrow> return ( (addrFromPPtr \<circ> regStart));
|
||||
regEnd \<leftarrow> return ( (snd \<circ> fromRegion));
|
||||
regEndPAddr \<leftarrow> return ( (addrFromPPtr \<circ> regEnd));
|
||||
slotBefore \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
mapM_x (\<lambda> i. provideUntypedCap rootCNodeCap i (fromIntegral pageBits) slotBefore)
|
||||
[regStartPAddr bootMemReuseReg, (regStartPAddr bootMemReuseReg + bit pageBits) .e. (regEndPAddr bootMemReuseReg - 1)];
|
||||
currSlot \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
mapM_x (\<lambda> _. (do
|
||||
paddr \<leftarrow> allocRegion pageBits;
|
||||
provideUntypedCap rootCNodeCap paddr (fromIntegral pageBits) slotBefore
|
||||
od)
|
||||
)
|
||||
[(currSlot - slotBefore) .e. (fromIntegral minNum4kUntypedObj - 1)];
|
||||
freemem \<leftarrow> noInitFailure $ gets initFreeMemory;
|
||||
(flip mapM) (take maxNumFreememRegions freemem)
|
||||
(\<lambda> reg. (
|
||||
(\<lambda> f. mapM (f reg) [4 .e. (finiteBitSize (undefined::machine_word)) - 2])
|
||||
(\<lambda> reg bits. (do
|
||||
reg' \<leftarrow> (if Not (isAligned (regStartPAddr reg) (bits + 1))
|
||||
\<and> (regEndPAddr reg) - (regStartPAddr reg) \<ge> bit bits
|
||||
then (do
|
||||
provideUntypedCap rootCNodeCap (regStartPAddr reg) (fromIntegral bits) slotBefore;
|
||||
return $ Region (regStart reg + bit bits, regEnd reg)
|
||||
od)
|
||||
else return reg);
|
||||
if Not (isAligned (regEndPAddr reg') (bits + 1)) \<and> (regEndPAddr reg') - (regStartPAddr reg') \<ge> bit bits
|
||||
then (do
|
||||
provideUntypedCap rootCNodeCap (regEndPAddr reg' - bit bits) (fromIntegral bits) slotBefore;
|
||||
return $ Region (regStart reg', regEnd reg' - bit bits)
|
||||
od)
|
||||
else return reg'
|
||||
od)
|
||||
)
|
||||
)
|
||||
);
|
||||
emptyReg \<leftarrow> return ( Region (PPtr 0, PPtr 0));
|
||||
freemem' \<leftarrow> return ( replicate maxNumFreememRegions emptyReg);
|
||||
slotAfter \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
noInitFailure $ modify (\<lambda> s. s \<lparr> initFreeMemory := freemem',
|
||||
initBootInfo := (initBootInfo s) \<lparr>
|
||||
bifUntypedObjCaps := [slotBefore .e. slotAfter - 1] \<rparr>\<rparr>)
|
||||
od)"
|
||||
|
||||
defs mapTaskRegions_def:
|
||||
"mapTaskRegions taskMappings\<equiv> (
|
||||
haskell_fail $ [] @ show taskMappings
|
||||
)"
|
||||
|
||||
defs allocFrame_def:
|
||||
"allocFrame \<equiv> allocRegion pageBits"
|
||||
|
||||
defs allocPage_def:
|
||||
"allocPage\<equiv> (do
|
||||
frame \<leftarrow> allocFrame;
|
||||
clr \<leftarrow> return ( (fromPPtr (ptrFromPAddr frame) `~shiftR~` pageBits)
|
||||
&& mask pageColourBits);
|
||||
(cptr, slot) \<leftarrow> allocRootSlotWithColour clr;
|
||||
doKernelOp $ (do
|
||||
cap \<leftarrow> createInitPage frame;
|
||||
byteLength \<leftarrow> return ( 1 `~shiftL~` pageBits);
|
||||
doMachineOp $ clearMemory (ptrFromPAddr frame) byteLength;
|
||||
insertInitCap slot cap
|
||||
od);
|
||||
return $ (VPtr $ fromCPtr cptr, ptrFromPAddr frame, slot)
|
||||
od)"
|
||||
|
||||
defs mapForInitTask_def:
|
||||
"mapForInitTask frame page\<equiv> (do
|
||||
slot \<leftarrow> requestRootSlot $ CPtr $ fromVPtr page;
|
||||
doKernelOp $ (do
|
||||
cap \<leftarrow> createInitPage frame;
|
||||
insertInitCap slot cap
|
||||
od)
|
||||
od)"
|
||||
|
||||
defs makeRootCNode_def:
|
||||
"makeRootCNode\<equiv> (do
|
||||
slotBits \<leftarrow> return ( objBits (undefined::cte));
|
||||
levelBits \<leftarrow> return ( rootCNodeSize);
|
||||
levelSize \<leftarrow> return ( 1 `~shiftL~` levelBits);
|
||||
frame \<leftarrow> liftM ptrFromPAddr $ allocRegion (levelBits + slotBits);
|
||||
rootCNCap \<leftarrow> doKernelOp $
|
||||
createObject (fromAPIType CapTableObject) frame levelBits;
|
||||
rootCNCap' \<leftarrow> return ( rootCNCap \<lparr>
|
||||
capCNodeGuardSize := finiteBitSize frame - pageBits - levelBits \<rparr>);
|
||||
rootSlots \<leftarrow> mapM (\<lambda> n. doKernelOp $ (do
|
||||
slot \<leftarrow> locateSlot (capCNodePtr rootCNCap') n;
|
||||
cptr \<leftarrow> return ( CPtr $ n `~shiftL~` pageBits);
|
||||
return (cptr, slot)
|
||||
od)
|
||||
) [0 .e. levelSize - 1];
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL1 := rootSlots \<rparr>);
|
||||
provideRegion $ BootRegion
|
||||
(CPtr 0) (CPtr $ (1 `~shiftL~` (pageBits+levelBits)) - 1)
|
||||
BRNodeL1 $ fromIntegral levelBits;
|
||||
return rootCNCap'
|
||||
od)"
|
||||
|
||||
defs allocRootSlot_def:
|
||||
"allocRootSlot\<equiv> (do
|
||||
freeSlots \<leftarrow> gets initFreeSlotsL1;
|
||||
(case freeSlots of
|
||||
result#rest \<Rightarrow> (do
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL1 := rest \<rparr>);
|
||||
return result
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
od)"
|
||||
|
||||
defs allocRootSlotWithColour_def:
|
||||
"allocRootSlotWithColour c\<equiv> (do
|
||||
freeSlots \<leftarrow> gets initFreeSlotsL1;
|
||||
matchingSlots \<leftarrow> return ( filter (\<lambda> slot.
|
||||
fromCPtr (fst slot) `~shiftR~` pageBits
|
||||
&& mask pageColourBits = c) freeSlots);
|
||||
(case matchingSlots of
|
||||
result#_ \<Rightarrow> (do
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL1 := delete result freeSlots \<rparr>);
|
||||
return result
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail $ [] @ show c @ []
|
||||
)
|
||||
od)"
|
||||
|
||||
defs requestRootSlot_def:
|
||||
"requestRootSlot addr\<equiv> (do
|
||||
freeSlots \<leftarrow> gets initFreeSlotsL1;
|
||||
(requested,others) \<leftarrow> return ( partition (\<lambda> x. fst x = addr) freeSlots);
|
||||
(case requested of
|
||||
[(_,result)] \<Rightarrow> (do
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL1 := others \<rparr>);
|
||||
return result
|
||||
od)
|
||||
| [] \<Rightarrow> haskell_fail $ [] @ show addr
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
od)"
|
||||
|
||||
defs makeSlots_def:
|
||||
"makeSlots\<equiv> (do
|
||||
slotBits \<leftarrow> return ( objBits (undefined::cte));
|
||||
slotSize \<leftarrow> return ( 1 `~shiftL~` slotBits);
|
||||
levelBits \<leftarrow> return ( pageBits - slotBits);
|
||||
levelSize \<leftarrow> return ( 1 `~shiftL~` levelBits);
|
||||
frame \<leftarrow> liftM ptrFromPAddr allocFrame;
|
||||
(cptr,slot) \<leftarrow> allocRootSlot;
|
||||
node \<leftarrow> doKernelOp $ (do
|
||||
cap \<leftarrow> createObject (fromAPIType CapTableObject)
|
||||
frame levelBits;
|
||||
cap' \<leftarrow> return ( cap \<lparr> capCNodeGuardSize := pageBits - levelBits \<rparr>);
|
||||
insertInitCap slot cap';
|
||||
return $ capCNodePtr cap'
|
||||
od);
|
||||
newSlots \<leftarrow> return ( map
|
||||
(\<lambda> n. (cptr + CPtr n, node + (slotSize * PPtr n)))
|
||||
[0 .e. levelSize - 1]);
|
||||
oldSlots \<leftarrow> gets initFreeSlotsL2;
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL2 := oldSlots @ newSlots \<rparr>);
|
||||
provideRegion $ BootRegion
|
||||
cptr (cptr - 1 + (CPtr $ 1 `~shiftL~` levelBits))
|
||||
BRNodeL2 $ fromIntegral levelBits
|
||||
slotBits \<leftarrow> return ( objBits (undefined::cte));
|
||||
levelBits \<leftarrow> return ( rootCNodeSize);
|
||||
frame \<leftarrow> liftM ptrFromPAddr $ allocRegion (levelBits + slotBits);
|
||||
rootCNCap \<leftarrow> doKernelOp $ createObject (fromAPIType CapTableObject) frame levelBits;
|
||||
rootCNCap \<leftarrow> return $ rootCNCap \<lparr>capCNodeGuardSize := 32 - levelBits\<rparr>;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNCap) biCapITCNode;
|
||||
doKernelOp $ insertInitCap slot rootCNCap;
|
||||
return rootCNCap
|
||||
od)"
|
||||
|
||||
defs provideCap_def:
|
||||
"provideCap cap\<equiv> (do
|
||||
freeSlots \<leftarrow> gets initFreeSlotsL2;
|
||||
when (freeSlots = []) makeSlots;
|
||||
freeSlots \<leftarrow> gets initFreeSlotsL2;
|
||||
(case freeSlots of
|
||||
(cptr,slot)#rest \<Rightarrow> (do
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL2 := rest \<rparr>);
|
||||
unless (isNullCap cap) $ doKernelOp $ insertInitCap slot cap;
|
||||
return (cptr, slot)
|
||||
od)
|
||||
| _ \<Rightarrow> haskell_fail []
|
||||
)
|
||||
"provideCap rootCNodeCap cap\<equiv> (do
|
||||
currSlot \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
maxSlot \<leftarrow> noInitFailure $ gets initSlotPosMax;
|
||||
when (currSlot \<ge> maxSlot) $ throwError InitFailure;
|
||||
slot \<leftarrow> doKernelOp $ locateSlot (capCNodePtr rootCNodeCap) currSlot;
|
||||
doKernelOp $ insertInitCap slot cap;
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initSlotPosCur := currSlot + 1 \<rparr>)
|
||||
od)"
|
||||
|
||||
defs provideRegion_def:
|
||||
"provideRegion r \<equiv> addRegionWithMerge r 0"
|
||||
defs provideUntypedCap_def:
|
||||
"provideUntypedCap rootCNodeCap pptr magnitudeBits slotPosBefore\<equiv> (do
|
||||
currSlot \<leftarrow> noInitFailure $ gets initSlotPosCur;
|
||||
i \<leftarrow> return ( currSlot - slotPosBefore);
|
||||
untypedObjs \<leftarrow> noInitFailure $ gets (bifUntypedObjPAddrs \<circ> initBootInfo);
|
||||
haskell_assert (length untypedObjs = fromIntegral i) [];
|
||||
untypedObjs' \<leftarrow> noInitFailure $ gets (bifUntypedObjSizeBits \<circ> initBootInfo);
|
||||
haskell_assert (length untypedObjs' = fromIntegral i) [];
|
||||
bootInfo \<leftarrow> noInitFailure $ gets initBootInfo;
|
||||
bootInfo' \<leftarrow> return ( bootInfo \<lparr> bifUntypedObjPAddrs := untypedObjs @ [pptr],
|
||||
bifUntypedObjSizeBits := untypedObjs' @ [magnitudeBits] \<rparr>);
|
||||
noInitFailure $ modify (\<lambda> st. st \<lparr> initBootInfo := bootInfo' \<rparr>);
|
||||
provideCap rootCNodeCap $ UntypedCap_ \<lparr>
|
||||
capPtr= ptrFromPAddr pptr,
|
||||
capBlockSize= fromIntegral magnitudeBits,
|
||||
capFreeIndex= 0 \<rparr>
|
||||
od)"
|
||||
|
||||
defs mergeBRs_def:
|
||||
"mergeBRs x0 x1 n\<equiv> (case (x0, x1) of
|
||||
((BootRegion a b BRLargeBlocks s), (BootRegion c d BRLargeBlocks t)) \<Rightarrow>
|
||||
if
|
||||
(b = c - 1) \<and> (s && mask n = s) \<and> (t && mask n = 0) then Just (BootRegion a d BRLargeBlocks (s || t))
|
||||
else if
|
||||
True then Nothing
|
||||
else undefined
|
||||
| ((BootRegion a b BRSmallBlocks s), (BootRegion c d BRSmallBlocks t)) \<Rightarrow>
|
||||
if
|
||||
(b = c - 1) \<and> (s = t) then Just (BootRegion a d BRSmallBlocks s)
|
||||
else if
|
||||
True then Nothing
|
||||
else undefined
|
||||
| ((BootRegion a b BRRootTask s), (BootRegion c d BRRootTask t)) \<Rightarrow>
|
||||
if
|
||||
(b = c - 1) \<and> (s = t) then Just (BootRegion a d BRRootTask s)
|
||||
else if
|
||||
True then Nothing
|
||||
else undefined
|
||||
| ((BootRegion b1 t1 BRDeviceCaps d1), (BootRegion b2 t2 BRDeviceCaps d2)) \<Rightarrow>
|
||||
defs coverOf_def:
|
||||
"coverOf x0\<equiv> (case x0 of
|
||||
[] \<Rightarrow> Region (0,0)
|
||||
| [x] \<Rightarrow> x
|
||||
| (x#xs) \<Rightarrow>
|
||||
let
|
||||
n1 = fromCPtr $ t1 - b1 + 1;
|
||||
s1 = fromIntegral $ d1 && mask 8;
|
||||
s2 = fromIntegral $ d2 && mask 8
|
||||
(l,h) = fromRegion x;;
|
||||
(ll,hh) = fromRegion $ coverOf xs;;
|
||||
ln = if l \<le> ll then l else ll;;
|
||||
hn = if h \<le> hh then hh else h
|
||||
in
|
||||
if
|
||||
(t1 = b2 - 1) \<and> (s1 = s2) \<and> (d1 `~shiftR~` s1 = (d2 `~shiftR~` s1) - n1) then Just (BootRegion b1 t2 BRDeviceCaps d1)
|
||||
else if
|
||||
True then Nothing
|
||||
else undefined
|
||||
| (_, _) \<Rightarrow> Nothing
|
||||
Region (ln, hn)
|
||||
)"
|
||||
|
||||
defs addRegionWithMerge_def:
|
||||
"addRegionWithMerge r n \<equiv>
|
||||
let
|
||||
tryMergeList = (\<lambda> xs. (case xs of
|
||||
[] \<Rightarrow> [r]
|
||||
| _ \<Rightarrow> (case mergeBRs (last xs) r n of
|
||||
None \<Rightarrow> xs @ [r]
|
||||
| Some r' \<Rightarrow> init xs @ [r']
|
||||
)
|
||||
))
|
||||
in
|
||||
(do
|
||||
regions \<leftarrow> gets initRegions;
|
||||
modify (\<lambda> st. st \<lparr> initRegions := tryMergeList regions \<rparr>)
|
||||
od)"
|
||||
|
||||
defs initKernel_def:
|
||||
"initKernel entry initFrames initOffset kernelFrames bootFrames\<equiv> (do
|
||||
pageSize \<leftarrow> return ( bit pageBits);
|
||||
wordSize \<leftarrow> return ( finiteBitSize entry);
|
||||
allMemory \<leftarrow> doMachineOp getMemoryRegions;
|
||||
allFrames \<leftarrow> return ( concat $
|
||||
map (\<lambda> (s, e). [s, s+pageSize .e. s+(e-s) - 1])
|
||||
allMemory);
|
||||
initPSpace $ map (\<lambda> (s, e). (ptrFromPAddr s, ptrFromPAddr e))
|
||||
allMemory;
|
||||
mapM (\<lambda> p. reserveFrame (ptrFromPAddr p) True) kernelFrames;
|
||||
initKernelVM;
|
||||
when (null initFrames)
|
||||
$ haskell_fail [];
|
||||
when (null kernelFrames)
|
||||
$ haskell_fail [];
|
||||
unless (distinct initFrames)
|
||||
$ haskell_fail [];
|
||||
unless (distinct kernelFrames)
|
||||
$ haskell_fail [];
|
||||
when (0 `~elem~` initFrames)
|
||||
$ haskell_fail [];
|
||||
when (0 `~elem~` kernelFrames)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (flip elem allFrames) initFrames)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (flip elem allFrames) kernelFrames)
|
||||
$ haskell_fail [];
|
||||
when (orList $ map (flip elem initFrames) kernelFrames)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (flip elem kernelFrames) bootFrames)
|
||||
$ haskell_fail [];
|
||||
unless (distinct allFrames)
|
||||
$ haskell_fail [];
|
||||
unless (isAligned (fromVPtr initOffset) pageBits)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (\<lambda> b. isAligned b pageBits) initFrames)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (\<lambda> b. isAligned b pageBits) kernelFrames)
|
||||
$ haskell_fail [];
|
||||
unless (distinct bootFrames)
|
||||
$ haskell_fail [];
|
||||
unless (andList $ map (\<lambda> (s, e). (e-s) < bit wordSize
|
||||
\<and> bit pageBits \<le> (e-s))
|
||||
allMemory) $ haskell_fail [];
|
||||
emptyFrames \<leftarrow> return (
|
||||
filter (flip notElem ([0] @ initFrames @ kernelFrames)) allFrames);
|
||||
freeGroups \<leftarrow> return ( rangesBy (\<lambda> a b. a + pageSize = b)
|
||||
(sort emptyFrames));
|
||||
freeMemory \<leftarrow> return (
|
||||
map (\<lambda> fs. (head fs, last fs + pageSize - 1)) freeGroups);
|
||||
bootGroups \<leftarrow> return ( rangesBy (\<lambda> a b. a + pageSize = b) bootFrames);
|
||||
bootMemory \<leftarrow> return (
|
||||
map (\<lambda> fs. (head fs, last fs + pageSize - 1)) bootGroups);
|
||||
(bootInfo, infoVPtr, infoPPtr, tcbCap) \<leftarrow>
|
||||
runInit freeMemory bootMemory $ (do
|
||||
rootCNCap \<leftarrow> makeRootCNode;
|
||||
makeSlots;
|
||||
initMappings \<leftarrow> return ( map
|
||||
(\<lambda> f. (f, (VPtr$fromIntegral f) - initOffset)) initFrames);
|
||||
(buffer, infoPtrs) \<leftarrow> mapTaskRegions initMappings;
|
||||
tcbCap \<leftarrow> createInitCaps rootCNCap buffer;
|
||||
createSmallBlockCaps;
|
||||
createDeviceCaps;
|
||||
untypedCount \<leftarrow> countUntypedCaps;
|
||||
freeSlotCount \<leftarrow> liftM length $ gets initFreeSlotsL2;
|
||||
when (freeSlotCount < untypedCount + minFreeSlots) $ (do
|
||||
makeSlots;
|
||||
untypedCount' \<leftarrow> countUntypedCaps;
|
||||
freeSlotCount' \<leftarrow> liftM length $ gets initFreeSlotsL2;
|
||||
haskell_assert (freeSlotCount' \<ge> untypedCount' + minFreeSlots) $
|
||||
[]
|
||||
od);
|
||||
createUntypedCaps;
|
||||
createFreeSlotRegions;
|
||||
createEmptyRegions;
|
||||
return (fst buffer, infoPtrs, tcbCap)
|
||||
od);
|
||||
bootInfoWords \<leftarrow> return ( wordsFromBootInfo bootInfo);
|
||||
intSize \<leftarrow> return ( finiteBitSize (undefined::machine_word) div 8);
|
||||
haskell_assert (length bootInfoWords * intSize < 1 `~shiftL~` pageBits) $
|
||||
[] @ show bootInfo;
|
||||
mapM_x
|
||||
(split storeWordUser
|
||||
)
|
||||
(zipE2 (infoPPtr) ( infoPPtr+(PPtr $ fromIntegral intSize)) (bootInfoWords));
|
||||
activateInitialThread (capTCBPtr tcbCap) entry infoVPtr
|
||||
od)"
|
||||
|
||||
defs mapTaskRegions_def:
|
||||
"mapTaskRegions taskMappings\<equiv> (do
|
||||
mapM (uncurry mapForInitTask) taskMappings;
|
||||
(bufferPtr,_,bufferSlot) \<leftarrow> allocPage;
|
||||
(infoVPtr,infoPPtr,_) \<leftarrow> allocPage;
|
||||
pages \<leftarrow> return ( sort $ map snd taskMappings);
|
||||
pageSize \<leftarrow> return ( 1 `~shiftL~` pageBits);
|
||||
pageGroups \<leftarrow> return ( [bufferPtr]#[infoVPtr]#
|
||||
rangesBy (\<lambda> a b. a + pageSize = b) pages);
|
||||
rootTaskRegions \<leftarrow> return (
|
||||
map (\<lambda> ps. BootRegion
|
||||
(CPtr $ fromVPtr $ head ps)
|
||||
(CPtr $ fromVPtr $ last ps + pageSize - 1)
|
||||
BRRootTask (fromIntegral pageBits))
|
||||
$ pageGroups);
|
||||
mapM_x provideRegion rootTaskRegions;
|
||||
return ((bufferPtr, bufferSlot), (infoVPtr, infoPPtr))
|
||||
od)"
|
||||
|
||||
defs createInitCaps_def:
|
||||
"createInitCaps rootCNCap x1\<equiv> (case x1 of
|
||||
(bufferPtr, bufferSlot) \<Rightarrow> (do
|
||||
(nullCapPtr,_) \<leftarrow> provideCap NullCap;
|
||||
haskell_assert (nullCapPtr = CPtr 0) [];
|
||||
tcbBits \<leftarrow> return ( objBits (undefined ::tcb));
|
||||
tcbFrame \<leftarrow> liftM ptrFromPAddr $ allocRegion $ tcbBits;
|
||||
idleFrame \<leftarrow> liftM ptrFromPAddr $ allocRegion $ tcbBits;
|
||||
tcbCap \<leftarrow> doKernelOp $ createObject (fromAPIType TCBObject) tcbFrame 0;
|
||||
idleCap \<leftarrow> doKernelOp $ createObject (fromAPIType TCBObject) idleFrame 0;
|
||||
provideCap tcbCap;
|
||||
(_,rootCNSlot) \<leftarrow> provideCap rootCNCap;
|
||||
(_,rootVNSlot) \<leftarrow> provideCap NullCap;
|
||||
irqCap \<leftarrow> initInterruptController;
|
||||
provideCap irqCap;
|
||||
provideCap DomainCap;
|
||||
initVSpace rootCNSlot rootVNSlot;
|
||||
doKernelOp $ (do
|
||||
threadCRoot \<leftarrow> getThreadCSpaceRoot (capTCBPtr tcbCap);
|
||||
cteInsert rootCNCap rootCNSlot threadCRoot;
|
||||
threadVRoot \<leftarrow> getThreadVSpaceRoot (capTCBPtr tcbCap);
|
||||
rootVNCap \<leftarrow> getSlotCap rootVNSlot;
|
||||
cteInsert rootVNCap rootVNSlot threadVRoot;
|
||||
threadSet (\<lambda> t. t \<lparr> tcbIPCBuffer := bufferPtr \<rparr>)
|
||||
(capTCBPtr tcbCap);
|
||||
threadBuffer \<leftarrow> getThreadBufferSlot (capTCBPtr tcbCap);
|
||||
bufferCap \<leftarrow> getSlotCap bufferSlot;
|
||||
bufferCap' \<leftarrow> nullCapOnFailure $ deriveCap bufferSlot bufferCap;
|
||||
cteInsert bufferCap' bufferSlot threadBuffer;
|
||||
setPriority (capTCBPtr tcbCap) maxPriority
|
||||
od);
|
||||
configureIdleThread (capTCBPtr idleCap);
|
||||
doKernelOp $ setIdleThread (capTCBPtr idleCap);
|
||||
firstFreeSlot \<leftarrow> liftM (fst \<circ> head) $ gets initFreeSlotsL2;
|
||||
provideRegion $ BootRegion (CPtr 0) (firstFreeSlot - 1) BRInitCaps 0;
|
||||
return tcbCap
|
||||
od)
|
||||
)"
|
||||
|
||||
defs createUntypedCaps_def:
|
||||
"createUntypedCaps\<equiv> (do
|
||||
freeRegions \<leftarrow> getUntypedRegions;
|
||||
modify (\<lambda> st. st \<lparr> initFreeMemory := [], initBootMemory := [] \<rparr>);
|
||||
blocks \<leftarrow> return ( concat (map (uncurry makeBlockList) freeRegions));
|
||||
mapM_x storeLargeBlock blocks
|
||||
od)"
|
||||
|
||||
defs storeLargeBlock_def:
|
||||
"storeLargeBlock x0\<equiv> (case x0 of
|
||||
(addr, bits) \<Rightarrow> (do
|
||||
ptr \<leftarrow> return ( ptrFromPAddr addr);
|
||||
(cptr, _) \<leftarrow> provideCap (UntypedCap ptr bits 0);
|
||||
addRegionWithMerge (BootRegion cptr cptr BRLargeBlocks (bit bits)) bits
|
||||
od)
|
||||
)"
|
||||
|
||||
defs makeBlockList_def:
|
||||
"makeBlockList s e \<equiv>
|
||||
let
|
||||
n = finiteBitSize s;
|
||||
magnitudes = [0 .e. n - 1];
|
||||
makeLowBlock = (\<lambda> ((start, end), xs, ys) b.
|
||||
if start !! b \<and> start \<le> end
|
||||
then ((start + bit b, end), (start, b) # xs, ys)
|
||||
else ((start, end), xs, ys));
|
||||
makeHighBlock = (\<lambda> ((start, end), xs, ys) b.
|
||||
if (end + 1) !! b \<and> start \<le> end
|
||||
then ((start, end - bit b), xs, (end - bit b + 1, b) # ys)
|
||||
else ((start, end), xs, ys));
|
||||
makeBlocks = (\<lambda> v b. makeLowBlock (makeHighBlock v b) b);
|
||||
result = foldl makeBlocks ((s, e), [], []) magnitudes;
|
||||
returnVal = (\<lambda> (_, low, high). reverse high @ reverse low)
|
||||
in
|
||||
returnVal result"
|
||||
|
||||
defs countUntypedCaps_def:
|
||||
"countUntypedCaps\<equiv> (do
|
||||
freeRegions \<leftarrow> getUntypedRegions;
|
||||
return $ sum $ map (\<lambda> (b,t). length (makeBlockList b t)) freeRegions
|
||||
od)"
|
||||
|
||||
defs getUntypedRegions_def:
|
||||
"getUntypedRegions\<equiv> gets (\<lambda> st. initFreeMemory st @ initBootMemory st)"
|
||||
|
||||
defs createDeviceCaps_def:
|
||||
"createDeviceCaps\<equiv> (do
|
||||
devices \<leftarrow> doKernelOp $ doMachineOp getDeviceRegions;
|
||||
forM_x devices (\<lambda> (base, end). (do
|
||||
cap \<leftarrow> doKernelOp $ createDeviceCap (base, end);
|
||||
(cptr,_) \<leftarrow> provideCap cap;
|
||||
rawmagnitude \<leftarrow> return ( end - base);
|
||||
sz \<leftarrow> return ( find (\<lambda> sz. rawmagnitude = bit (pageBitsForSize sz))
|
||||
[minBound .e. maxBound]);
|
||||
magnitude \<leftarrow> (case sz of
|
||||
Some magnitude \<Rightarrow> return $ pageBitsForSize magnitude
|
||||
| None \<Rightarrow> haskell_fail []
|
||||
);
|
||||
provideRegion $ BootRegion cptr cptr BRDeviceCaps
|
||||
(fromIntegral base || fromIntegral magnitude)
|
||||
od))
|
||||
od)"
|
||||
|
||||
defs createSmallBlockCaps_def:
|
||||
"createSmallBlockCaps\<equiv> (do
|
||||
caps \<leftarrow> replicateM minSmallBlocks $ (do
|
||||
frame \<leftarrow> liftM ptrFromPAddr allocFrame;
|
||||
return $ UntypedCap frame pageBits 0
|
||||
od);
|
||||
storeSmallBlockCaps caps
|
||||
od)"
|
||||
|
||||
defs storeSmallBlockCaps_def:
|
||||
"storeSmallBlockCaps \<equiv> mapM_x storeSmallBlockCap"
|
||||
|
||||
defs storeSmallBlockCap_def:
|
||||
"storeSmallBlockCap cap\<equiv> (do
|
||||
(cptr, _) \<leftarrow> provideCap cap;
|
||||
dWord \<leftarrow> return ( fromIntegral pageBits);
|
||||
provideRegion $ BootRegion cptr cptr BRSmallBlocks dWord
|
||||
od)"
|
||||
|
||||
defs createFreeSlotRegions_def:
|
||||
"createFreeSlotRegions\<equiv> (do
|
||||
slots \<leftarrow> gets initFreeSlotsL2;
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL2 := [] \<rparr>);
|
||||
haskell_assert (length slots \<ge> minFreeSlots) $
|
||||
[] @ show (length slots) @
|
||||
[] @ show minFreeSlots;
|
||||
ranges \<leftarrow> return ( rangesBy (\<lambda> a b. a = b - 1) $ sort $ map fst slots);
|
||||
mapM_x (\<lambda> slots. provideRegion $
|
||||
BootRegion (head slots) (last slots) BRFreeSlots 0
|
||||
) ranges
|
||||
od)"
|
||||
|
||||
defs createEmptyRegions_def:
|
||||
"createEmptyRegions\<equiv> (do
|
||||
l1magnitude \<leftarrow> return ( bit (pageBits + rootCNodeSize));
|
||||
slots \<leftarrow> gets initFreeSlotsL1;
|
||||
modify (\<lambda> st. st \<lparr> initFreeSlotsL1 := [] \<rparr>);
|
||||
pageSize \<leftarrow> return ( 1 `~shiftL~` pageBits);
|
||||
ranges \<leftarrow> return ( rangesBy (\<lambda> a b. a + pageSize = b) $ sort $ map fst slots);
|
||||
mapM_x (\<lambda> slots. provideRegion $
|
||||
BootRegion (head slots) (last slots + pageSize - 1) BREmpty 0
|
||||
) ranges;
|
||||
provideRegion $ BootRegion l1magnitude maxBound BREmpty 0
|
||||
od)"
|
||||
|
||||
|
||||
consts
|
||||
newKSDomSchedule :: "(domain \<times> machine_word) list"
|
||||
|
|
|
@ -133,7 +133,7 @@ defs deleteObjects_def:
|
|||
[];
|
||||
doMachineOp $ freeMemory (PPtr (fromPPtr ptr)) bits;
|
||||
ps \<leftarrow> gets ksPSpace;
|
||||
inRange \<leftarrow> return ( (\<lambda> x. x && (- mask bits) - 1 = fromPPtr ptr));
|
||||
inRange \<leftarrow> return ( (\<lambda> x. x && ((- mask bits) - 1) = fromPPtr ptr));
|
||||
map' \<leftarrow> return ( data_map_filterWithKey
|
||||
(\<lambda> x _. Not (inRange x))
|
||||
(psMap ps));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,12 +22,60 @@ begin
|
|||
definition
|
||||
initKernelVM :: "unit kernel"
|
||||
where
|
||||
"initKernelVM \<equiv> ArchVSpaceDecls_H.initKernelVM"
|
||||
"initKernelVM \<equiv> ArchVSpaceDecls_H.mapKernelWindow"
|
||||
|
||||
definition
|
||||
initVSpace :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit kernel_init"
|
||||
initPlatform :: "unit kernel"
|
||||
where
|
||||
"initVSpace \<equiv> ArchVSpaceDecls_H.initVSpace"
|
||||
"initPlatform\<equiv> (do
|
||||
doMachineOp $ configureTimer;
|
||||
doMachineOp $ initL2Cache
|
||||
od)"
|
||||
|
||||
definition
|
||||
initCPU :: "unit kernel"
|
||||
where
|
||||
"initCPU \<equiv> ArchVSpaceDecls_H.activateGlobalPD"
|
||||
|
||||
definition
|
||||
createIPCBufferFrame :: "capability \<Rightarrow> vptr \<Rightarrow> capability kernel_init"
|
||||
where
|
||||
"createIPCBufferFrame \<equiv> ArchVSpaceDecls_H.createIPCBufferFrame"
|
||||
|
||||
definition
|
||||
createBIFrame :: "capability \<Rightarrow> vptr \<Rightarrow> word32 \<Rightarrow> word32 \<Rightarrow> capability kernel_init"
|
||||
where
|
||||
"createBIFrame \<equiv> ArchVSpaceDecls_H.createBIFrame"
|
||||
|
||||
definition
|
||||
createFramesOfRegion :: "capability \<Rightarrow> region \<Rightarrow> bool \<Rightarrow> vptr \<Rightarrow> unit kernel_init"
|
||||
where
|
||||
"createFramesOfRegion \<equiv> ArchVSpaceDecls_H.createFramesOfRegion"
|
||||
|
||||
definition
|
||||
createITPDPTs :: "capability \<Rightarrow> vptr \<Rightarrow> vptr \<Rightarrow> capability kernel_init"
|
||||
where
|
||||
"createITPDPTs \<equiv> ArchVSpaceDecls_H.createITPDPTs"
|
||||
|
||||
definition
|
||||
writeITPDPTs :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel_init"
|
||||
where
|
||||
"writeITPDPTs \<equiv> ArchVSpaceDecls_H.writeITPDPTs"
|
||||
|
||||
definition
|
||||
createITASIDPool :: "capability \<Rightarrow> capability kernel_init"
|
||||
where
|
||||
"createITASIDPool \<equiv> ArchVSpaceDecls_H.createITASIDPool"
|
||||
|
||||
definition
|
||||
writeITASIDPool :: "capability \<Rightarrow> capability \<Rightarrow> unit kernel"
|
||||
where
|
||||
"writeITASIDPool \<equiv> ArchVSpaceDecls_H.writeITASIDPool"
|
||||
|
||||
definition
|
||||
createDeviceFrames :: "capability \<Rightarrow> unit kernel_init"
|
||||
where
|
||||
"createDeviceFrames \<equiv> ArchVSpaceDecls_H.createDeviceFrames"
|
||||
|
||||
definition
|
||||
handleVMFault :: "machine_word \<Rightarrow> vmfault_type \<Rightarrow> ( fault , unit ) kernel_f"
|
||||
|
@ -49,15 +97,5 @@ lookupIPCBuffer :: "bool \<Rightarrow> machine_word \<Rightarrow> ((machine_word
|
|||
where
|
||||
"lookupIPCBuffer \<equiv> ArchVSpaceDecls_H.lookupIPCBuffer"
|
||||
|
||||
definition
|
||||
createInitPage :: "paddr \<Rightarrow> capability kernel"
|
||||
where
|
||||
"createInitPage \<equiv> ArchVSpaceDecls_H.createInitPage"
|
||||
|
||||
definition
|
||||
createDeviceCap :: "(paddr * paddr) \<Rightarrow> capability kernel"
|
||||
where
|
||||
"createDeviceCap \<equiv> ArchVSpaceDecls_H.createDeviceCap"
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
Built from git repo at /home/jbeeren/nfshome/work/fp/seL4/haskell by jbeeren
|
||||
|
||||
Generated from changeset:
|
||||
a3c1a39 Minor change to haskell implementation of armv_contextSwitch
|
||||
3105c61 Merge branch 'master' into context-switch
|
||||
|
||||
|
||||
Warning - uncomitted changes used:
|
||||
M src/SEL4/Kernel/VSpace/ARM.lhs
|
||||
?? ../api/
|
||||
?? ../arch/
|
||||
?? ../kernel.elf
|
||||
|
|
Loading…
Reference in New Issue