Komodo/verified/kom_utils.sdfy

264 строки
7.9 KiB
Plaintext

include {:verbatim} "kom_common.i.dfy"
include {:verbatim} "bitvectors.i.dfy"
include {:verbatim} "pagedb.i.dfy"
include "ARMdecls.sdfy"
procedure page_paddr_impl(out operand phys:reg, operand pagenr:reg, out operand tmp:reg)
reads
globals;
requires/ensures
SaneState(this);
requires
// NB: @phys == @pagenr is supported
@phys != @tmp;
@pagenr != @tmp;
@phys != OSP;
@tmp != OSP;
validPageNr(pagenr);
ensures
//SmcProcedureInvariant(old(this), this);
phys == page_paddr(old(pagenr));
PageAligned(phys);
{
assert pagenr < KOM_SECURE_NPAGES;
lemma_LeftShift12(pagenr);
LSL(phys, pagenr, 12);
assert phys == old(pagenr) * PAGESIZE;
LDRglobaladdr(tmp, SecurePhysBaseOp());
LDRglobal(tmp, SecurePhysBaseOp(), tmp, 0);
assert WordAligned(tmp);
ADD(phys, phys, tmp);
}
procedure paddr_page_impl(out operand pagenr:reg, operand phys:reg, out operand tmp:reg)
reads
globals;
requires/ensures
SaneState(this);
requires
// NB: @phys == @pagenr is supported
@phys != @tmp;
@pagenr != @tmp;
@tmp != OSP;
@pagenr != OSP;
PageAligned(phys);
SecurePhysBase() <= phys < SecurePhysBase() + KOM_SECURE_RESERVE;
ensures
//SmcProcedureInvariant(old(this), this);
pagenr == paddr_page(old(phys));
validPageNr(pagenr);
{
LDRglobaladdr(tmp, SecurePhysBaseOp());
LDRglobal(tmp, SecurePhysBaseOp(), tmp, 0);
assert WordAligned(tmp);
SUB(pagenr,phys,tmp);
ghost var oldpagenr := pagenr;
LSR(pagenr, pagenr, 12);
lemma_RightShift12(oldpagenr);
assert pagenr == oldpagenr / PAGESIZE;
}
procedure page_monvaddr_impl(out operand virt:reg, operand pagenr:reg, out operand tmp:reg)
reads
globals;
requires/ensures
SaneState(this);
requires
// NB: @pagenr == @virt is supported
@pagenr != @tmp;
@virt != @tmp;
@virt != OSP;
@tmp != OSP;
validPageNr(pagenr);
ensures
//SmcProcedureInvariant(old(this), this);
virt == page_monvaddr(old(pagenr));
{
page_paddr_impl(virt, pagenr, tmp);
ADD(virt, virt, const(KOM_DIRECTMAP_VBASE));
}
procedure stack_nonvolatiles(ghost stack_bytes:int) returns (ghost stack_bytes_ret:int)
reads
r4; r5; r6; r7; r8; r9; r10; r11; r12; lr;
modifies
sp; mem;
requires/ensures
SaneState(this);
requires
stack_bytes >= 40;
StackBytesRemaining(this,stack_bytes);
ensures
sp == old(sp-40);
//preserves registers
//RegPreservingExcept(old(this), this, set(@sp));
// pushes r4-r11, sp, lr
MemContents(this.m, sp) == old(r12);
MemContents(this.m, sp+4) == old(r11);
MemContents(this.m, sp+8) == old(r10);
MemContents(this.m, sp+12) == old(r9);
MemContents(this.m, sp+16) == old(r8);
MemContents(this.m, sp+20) == old(r7);
MemContents(this.m, sp+24) == old(r6);
MemContents(this.m, sp+28) == old(r5);
MemContents(this.m, sp+32) == old(r4);
MemContents(this.m, sp+36) == old(lr);
//GlobalsInvariant(old(this),this);
//BankedRegsInvariant(old(this),this);
//SRegsInvariant(old(this),this);
NonStackMemPreserving(old(this),this);
ParentStackPreserving(old(this),this);
stack_bytes_ret == stack_bytes-40;
StackBytesRemaining(this,stack_bytes_ret);
{
SUB(sp, sp, 40);
STR(lr, sp, 36);
STR(r4, sp, 32);
STR(r5, sp, 28);
STR(r6, sp, 24);
STR(r7, sp, 20);
STR(r8, sp, 16);
STR(r9, sp, 12);
STR(r10, sp, 8);
STR(r11, sp, 4);
STR(r12, sp, 0);
stack_bytes_ret := stack_bytes - 40;
}
procedure unstack_nonvolatiles(ghost stack_bytes:int) returns (ghost stack_bytes_ret:int)
reads
mem;
modifies
r4; r5; r6; r7; r8; r9; r10; r11; r12; lr; sp;
requires/ensures
SaneState(this);
requires
isUInt32(sp + 40);
sp + 40 <= StackBase();
StackBytesRemaining(this, stack_bytes);
ensures
sp == old(sp+40);
// fcall argument regs preserved.
//r0 == old(r0);
//r1 == old(r1);
//r2 == old(r2);
//r3 == old(r3);
// pop lr, r4-r11 from stack.
lr == old(MemContents(this.m, sp+36));
r4 == old(MemContents(this.m, sp+32));
r5 == old(MemContents(this.m, sp+28));
r6 == old(MemContents(this.m, sp+24));
r7 == old(MemContents(this.m, sp+20));
r8 == old(MemContents(this.m, sp+16));
r9 == old(MemContents(this.m, sp+12));
r10 == old(MemContents(this.m, sp+8));
r11 == old(MemContents(this.m, sp+4));
r12 == old(MemContents(this.m, sp));
//AllMemInvariant(old(this),this);
//BankedRegsInvariant(old(this),this);
//SRegsInvariant(old(this),this);
stack_bytes_ret == stack_bytes + 40;
StackBytesRemaining(this, stack_bytes_ret);
{
//pop r12 down to r4 from stack
LDR(r12, sp, 0);
LDR(r11, sp, 4);
LDR(r10, sp, 8);
LDR(r9, sp, 12);
LDR(r8, sp, 16);
LDR(r7, sp, 20);
LDR(r6, sp, 24);
LDR(r5, sp, 28);
LDR(r4, sp, 32);
//pop link register from stack
LDR(lr, sp, 36);
ADD(sp, sp, 40);
stack_bytes_ret := stack_bytes + 40;
}
procedure load_page_type(
operand pagenr:reg,
operand pagedb_base:addr,
out operand offset:reg,
out operand pgtype:reg,
ghost pagedb:PageDb)
requires/ensures
SaneState(this);
requires
validPageNr(pagenr);
pagedb_base == AddressOfGlobal(PageDb());
@pgtype != OSP && @offset != OSP && @offset != @pagedb_base;
validPageDb(pagedb);
pageDbCorresponds(this.m, pagedb);
reads
globals;
ensures
pgtype == pageDbEntryTypeVal(pagedb[old(pagenr)]);
@offset != @pgtype ==> offset == G_PAGEDB_ENTRY(old(pagenr));
{
lemma_LeftShift3(pagenr);
LSL(offset, pagenr, const(PAGEDB_ENTRY_SHIFT));
assert offset == G_PAGEDB_ENTRY(old(pagenr)) + PAGEDB_ENTRY_TYPE;
LDRglobal(pgtype, PageDb(), pagedb_base, offset);
reveal pageDbEntryCorresponds;
PageDbCorrespondsImpliesEntryCorresponds(this.m, pagedb, old(pagenr));
extractPageDbToAbstractOne(this.m, old(pagenr), PAGEDB_ENTRY_TYPE);
}
procedure update_pagedb_entry(
ghost page:PageNr,
ghost gentry:PageDbEntry,
inout operand entry:reg,
operand typeword:reg,
operand as_va:reg,
operand pagedb_base:reg)
requires/ensures
SaneState(this);
requires
validPageNr(page);
wellFormedPageDbEntry(gentry);
gentry is PageDbEntryTyped;
as_va == page_monvaddr(gentry.addrspace);
typeword == pageDbEntryTypeVal(gentry);
entry == G_PAGEDB_ENTRY(page);
pagedb_base == AddressOfGlobal(PageDb());
@entry != @as_va && @entry != @pagedb_base;
modifies
globals;
ensures
SmcProcedureInvariant(old(this), this);
GlobalsPreservingExcept(old(this), this, set(PageDb()));
pageDbEntryCorresponds(gentry, extractPageDbEntry(this.m, page));
forall p :: validPageNr(p) && p != page
==> extractPageDbEntry(old(this).m, p) == extractPageDbEntry(this.m, p);
{
STRglobal(typeword, PageDb(), pagedb_base, entry);
assert GlobalWord(this.m, PageDb(), G_PAGEDB_ENTRY(page)
+ PAGEDB_ENTRY_TYPE) == old(typeword);
ADD(entry, entry, const(PAGEDB_ENTRY_ADDRSPACE));
assert entry == G_PAGEDB_ENTRY(page) + PAGEDB_ENTRY_ADDRSPACE;
STRglobal(as_va, PageDb(), pagedb_base, entry);
assert GlobalWord(this.m, PageDb(), G_PAGEDB_ENTRY(page)
+ PAGEDB_ENTRY_ADDRSPACE) == old(as_va);
extractPageDbToAbstract(this.m, page);
assert extractPageDbEntry(this.m, page) == seq(old(typeword), old(as_va));
reveal pageDbEntryCorresponds;
}