lh-l4v/spec/machine/AARCH64/Platform.thy

165 lines
4.8 KiB
Plaintext

(*
* Copyright 2022, Proofcraft Pty Ltd
*
* SPDX-License-Identifier: GPL-2.0-only
*)
chapter "Platform Definitions"
theory Platform
imports
"Lib.Lib"
"Word_Lib_l4v.WordSetup"
"Lib.Defs"
Setup_Locale
Kernel_Config
begin
context Arch begin global_naming AARCH64
type_synonym irq_len = 9 (* match IRQ_CNODE_SLOT_BITS in seL4 config *)
type_synonym irq = "irq_len word"
type_synonym paddr = machine_word
abbreviation (input) "toPAddr \<equiv> id"
abbreviation (input) "fromPAddr \<equiv> id"
(* For address space layout with hypervisor enabled see:
seL4/include/arch/arm/arch/64/mode/hardware.h
FIXME AARCH64 include diagram here after C revisions are done
*)
(* NOTE: a number of these constants appear in the Haskell, but are shadowed
here due to more convenient formulation.
Examples: kernelELFBase, kernelELFBaseOffset, kernelELFAddressBase, pptrBase
Ideally and in future, we should converge on a single authoritative source
of these constants.
*)
(* The canonical bit is the highest bit that can be set in a virtual address and still accepted
by the hardware. Any bit higher than that will be overwritten by sign extension, zero extension,
or result in a fault.
For AArch64 with hyp, addresses >= 2^48 are invalid, and sign-extension is not used by the
hardware. *)
definition canonical_bit :: nat where
"canonical_bit = 47"
definition kdevBase :: machine_word where
"kdevBase = 0x000000FFFFE00000"
definition kernelELFBase :: machine_word where
"kernelELFBase = 2^39 + physBase"
definition kernelELFPAddrBase :: machine_word where
"kernelELFPAddrBase = physBase"
definition kernelELFBaseOffset :: machine_word where
"kernelELFBaseOffset = kernelELFBase - kernelELFPAddrBase"
definition pptrBase :: machine_word where
"pptrBase = 0x8000000000" (* 2^39 *)
definition pptrUserTop :: machine_word where
"pptrUserTop \<equiv> mask (if config_ARM_PA_SIZE_BITS_40 then 40 else 44)"
lemma "pptrUserTop = (if config_ARM_PA_SIZE_BITS_40 then 0xFFFFFFFFFF else 0xFFFFFFFFFFF)" (* Sanity check with C *)
by (simp add: pptrUserTop_def mask_def)
definition pptrTop :: machine_word where
"pptrTop = 2^40 - 2^30" (* FIXME AARCH64: see also seL4/seL4#957 *)
definition paddrBase :: machine_word where
"paddrBase \<equiv> 0"
definition pptrBaseOffset :: machine_word where
"pptrBaseOffset = pptrBase - paddrBase"
definition paddrTop :: machine_word where
"paddrTop = pptrTop - pptrBaseOffset"
definition ptrFromPAddr :: "paddr \<Rightarrow> machine_word" where
"ptrFromPAddr paddr \<equiv> paddr + pptrBaseOffset"
definition addrFromPPtr :: "machine_word \<Rightarrow> paddr" where
"addrFromPPtr pptr \<equiv> pptr - pptrBaseOffset"
definition addrFromKPPtr :: "machine_word \<Rightarrow> paddr" where
"addrFromKPPtr pptr \<equiv> pptr - kernelELFBaseOffset"
definition minIRQ :: "irq" where
"minIRQ \<equiv> 0"
definition maxIRQ :: "irq" where
"maxIRQ \<equiv> 383"
definition irqVGICMaintenance :: irq where
"irqVGICMaintenance \<equiv> 25"
definition irqVTimerEvent :: irq where
"irqVTimerEvent \<equiv> 27"
definition pageColourBits :: nat where
"pageColourBits \<equiv> undefined" \<comment> \<open>not implemented on this platform\<close>
section \<open>Page table sizes\<close>
definition vs_index_bits :: nat where
"vs_index_bits \<equiv> if config_ARM_PA_SIZE_BITS_40 then 10 else (9::nat)"
end
(* Need to declare code equation outside Arch locale *)
declare AARCH64.vs_index_bits_def[code]
context Arch begin global_naming AARCH64
lemma vs_index_bits_ge0[simp, intro!]: "0 < vs_index_bits"
by (simp add: vs_index_bits_def)
(* A dependent-ish type in Isabelle. We use typedef here instead of value_type so that we can
retain a symbolic value (vs_index_bits) for the size of the type instead of getting a plain
number such as 9 or 10. *)
typedef vs_index_len = "{n :: nat. n < vs_index_bits}" by auto
end
instantiation AARCH64.vs_index_len :: len0
begin
interpretation Arch .
definition len_of_vs_index_len: "len_of (x::vs_index_len itself) \<equiv> CARD(vs_index_len)"
instance ..
end
instantiation AARCH64.vs_index_len :: len
begin
interpretation Arch .
instance
proof
show "0 < LENGTH(vs_index_len)"
by (simp add: len_of_vs_index_len type_definition.card[OF type_definition_vs_index_len])
qed
end
context Arch begin global_naming AARCH64
type_synonym vs_index = "vs_index_len word"
type_synonym pt_index_len = 9
type_synonym pt_index = "pt_index_len word"
text \<open>Sanity check:\<close>
lemma length_vs_index_len[simp]:
"LENGTH(vs_index_len) = vs_index_bits"
by (simp add: len_of_vs_index_len type_definition.card[OF type_definition_vs_index_len])
section \<open>C array sizes corresponding to page table sizes\<close>
value_type pt_array_len = "(2::nat) ^ LENGTH(pt_index_len)"
value_type vs_array_len = "(2::nat) ^ vs_index_bits"
end
end