@@ -800,10 +800,12 @@ Module TLB.
800800 Module Entry.
801801 Record t (lvl : Level) :=
802802 make {
803+ is_upper : bool;
803804 val_ttbr : val;
804805 ptes : vec val (S lvl);
805806 }.
806- Arguments make {_} _ _.
807+ Arguments make {_} _ _ _.
808+ Arguments is_upper {_}.
807809 Arguments val_ttbr {_}.
808810 Arguments ptes {_}.
809811
@@ -815,8 +817,8 @@ Module TLB.
815817
816818 #[global] Instance count lvl : Countable (t lvl).
817819 Proof .
818- eapply (inj_countable' (fun ent => (val_ttbr ent, ptes ent))
819- (fun x => make x.1 x.2)).
820+ eapply (inj_countable' (fun ent => (is_upper ent, val_ttbr ent, ptes ent))
821+ (fun x => make x.1.1 x.1.2 x.2)).
820822 abstract sauto.
821823 Defined .
822824
@@ -826,7 +828,7 @@ Module TLB.
826828 (tlbe : t lvl)
827829 (pte : val)
828830 (CHILD : lvl + 1 = clvl) : t clvl :=
829- make tlbe.(val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
831+ make tlbe.(is_upper) tlbe.( val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
830832 Solve All Obligations with lia.
831833 End Entry.
832834 Export (hints) Entry.
@@ -934,6 +936,15 @@ Module TLB.
934936 (CHILD : (Ctxt.lvl ctxt) + 1 = clvl) : prefix clvl :=
935937 bv_concat (level_length clvl) (Ctxt.va ctxt) index.
936938
939+ Definition is_upper_ttbr (ttbr : reg) : option bool :=
940+ if decide
941+ (ttbr = TTBR0_EL1 ∨
942+ ttbr = TTBR0_EL2 ∨
943+ ttbr = TTBR0_EL3) then Some false
944+ else if decide
945+ (ttbr = TTBR1_EL1 ∨
946+ ttbr = TTBR1_EL2) then Some true
947+ else None.
937948
938949 (** Seed root-level TLB entries from [ttbr].
939950 - Reads [ttbr] at [time], checks it is 64-bit.
@@ -950,6 +961,7 @@ Module TLB.
950961 (ttbr : reg) : result string (VATLB.t * bool) :=
951962 sregs ← othrow "TTBR should exist in initial state"
952963 $ TState.read_sreg_at ts ttbr time;
964+ is_upper ← othrow "The register is not TTBR" (is_upper_ttbr ttbr);
953965 foldlM (λ '(vatlb, is_changed) sreg,
954966 val_ttbr ← othrow "TTBR should be a 64 bit value"
955967 $ regval_to_val ttbr sreg.1;
@@ -961,7 +973,7 @@ Module TLB.
961973 let ndctxt := NDCtxt.make va (Some asid) in
962974 let ctxt := existT root_lvl ndctxt in
963975 let entry : Entry.t (Ctxt.lvl ctxt) :=
964- Entry.make val_ttbr ([#memval] : vec val (S root_lvl)) in
976+ Entry.make is_upper val_ttbr ([#memval] : vec val (S root_lvl)) in
965977 (* add the entry to vatlb only when it is not in the original vatlb *)
966978 if decide (entry ∉ (VATLB.get ctxt vatlb)) then
967979 Ok (VATLB.insert ctxt entry vatlb, true)
@@ -1207,26 +1219,27 @@ Module TLB.
12071219 (tlb : t) (trans_time : nat)
12081220 (lvl : Level)
12091221 (ndctxt : NDCtxt.t lvl) :
1210- result string (list (list val * (option nat))) :=
1222+ result string (list (val * list val * (option nat))) :=
12111223 let ctxt := existT lvl ndctxt in
12121224 let tes := VATLB.get ctxt tlb.(TLB.vatlb) in
12131225 let tes := if decide (lvl = leaf_lvl) then tes
12141226 else filter (λ te, is_block (TLB.Entry.pte te)) tes in
12151227 for te in (elements tes) do
12161228 ti ← invalidation_time mem tid trans_time ctxt te;
1217- mret ((vec_to_list (Entry.ptes te)), ti)
1229+ mret ((Entry.val_ttbr te), ( vec_to_list (Entry.ptes te)), ti)
12181230 end .
12191231
1220- (** Get all the TLB entries that could translate the given VA
1221- at the provided level and in the provided ASID context.
1232+ (** Get all the TLB entries and the corresponding TTBR value that
1233+ could translate the given VA at the provided level
1234+ and in the provided ASID context.
12221235 Return each TLB entry as a list of descriptors [list val] with
12231236 the invalidation time [nat] *)
12241237 Definition get_leaf_ptes_with_inv_time (mem : Memory.t)
12251238 (tid : nat)
12261239 (tlb : t) (trans_time : nat)
12271240 (lvl : Level)
12281241 (va : bv 64) (asid : bv 16) :
1229- result string (list (list val * (option nat))) :=
1242+ result string (list (val * list val * (option nat))) :=
12301243 let ndctxt_asid := NDCtxt.make (level_prefix va lvl) (Some asid) in
12311244 let ndctxt_global := NDCtxt.make (level_prefix va lvl) None in
12321245 candidates_asid ←
@@ -1235,21 +1248,22 @@ Module TLB.
12351248 get_leaf_ptes_with_inv_time_by_ctxt mem tid tlb trans_time lvl ndctxt_global;
12361249 mret (candidates_asid ++ candidates_global)%list.
12371250
1238- (** Get all the TLB entries that could translate the given VA
1239- in the provided ASID context.
1251+ (** Get all the TLB entries and the corresponding TTBR value that
1252+ could translate the given VA in the provided ASID context.
12401253 Return each TLB entry as a list of descriptors [list val] with
12411254 the invalidation time [nat] *)
12421255 Definition lookup (mem : Memory.t)
12431256 (tid : nat)
12441257 (tlb : TLB.t) (trans_time : nat)
12451258 (va : bv 64) (asid : bv 16) :
1246- result string (list (list val * (option nat))) :=
1259+ result string (list (val * list val * (option nat))) :=
12471260 res1 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time 1%fin va asid;
12481261 res2 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time 2%fin va asid;
12491262 res3 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time leaf_lvl va asid;
12501263 mret (res1 ++ res2 ++ res3).
12511264
1252- (** Get all the TLB entries that trigger fault from the given VA
1265+ (** Get all the TLB entries and the corresponding TTBR value that
1266+ trigger fault from the given VA
12531267 at the provided level and in the provided ASID context.
12541268 Return each TLB entry as a list of descriptors [list val] with
12551269 the invalidation time [option nat] *)
@@ -1261,7 +1275,8 @@ Module TLB.
12611275 (lvl : Level)
12621276 (va : bv 64)
12631277 (asid : option (bv 16))
1264- (ttbr : reg) : result string (list (list val * (option nat))) :=
1278+ (ttbr : reg) :
1279+ result string (list (val * list val * (option nat))) :=
12651280 if parent_lvl lvl is Some parent_lvl then
12661281 let ndctxt := NDCtxt.make (level_prefix va parent_lvl) asid in
12671282 let ctxt := existT parent_lvl ndctxt in
@@ -1276,7 +1291,8 @@ Module TLB.
12761291 if decide (is_valid memval) then mret None
12771292 else
12781293 ti ← invalidation_time mem tid trans_time ctxt te;
1279- mret $ Some ((vec_to_list (Entry.ptes te)) ++ [memval], ti)
1294+ let vals := (vec_to_list (Entry.ptes te)) ++ [memval] in
1295+ mret $ Some (Entry.val_ttbr te, vals, ti)
12801296 else
12811297 mthrow "The PTE is missing"
12821298 end ;
@@ -1294,22 +1310,25 @@ Module TLB.
12941310 if (Memory.read_at loc init mem trans_time) is Some (memval, _) then
12951311 if decide (is_valid memval) then mret None
12961312 else
1297- mret $ Some ([memval], None)
1313+ mret $ Some (val_ttbr, [memval], None)
12981314 else mthrow "The root PTE is missing"
12991315 end ;
13001316 mret $ omap id invalid_ptes.
13011317
1302- (** Get all the TLB entries that trigger fault from the given VA
1318+ (** Get all the TLB entries and the corresponding TTBR value that
1319+ trigger fault from the given VA
13031320 in the provided ASID context.
13041321 Return each TLB entry as a list of descriptors [list val] with
13051322 the invalidation time [option nat] *)
1306- Definition get_invalid_ptes_with_inv_time_by_lvl (ts : TState.t) (init : Memory.initial)
1323+ Definition get_invalid_ptes_with_inv_time_by_lvl (ts : TState.t)
1324+ (init : Memory.initial)
13071325 (mem : Memory.t)
13081326 (tid : nat)
13091327 (tlb : t) (trans_time : nat)
13101328 (lvl : Level)
13111329 (va : bv 64) (asid : bv 16)
1312- (ttbr : reg) : result string (list (list val * (option nat))) :=
1330+ (ttbr : reg) :
1331+ result string (list (val * list val * (option nat))) :=
13131332 candidates_asid ←
13141333 get_invalid_ptes_with_inv_time_by_lvl_asid
13151334 ts init mem tid tlb trans_time lvl va (Some asid) ttbr;
@@ -1324,7 +1343,7 @@ Module TLB.
13241343 (tlb : TLB.t) (time : nat)
13251344 (va : bv 64) (asid : bv 16)
13261345 (ttbr : reg) :
1327- result string (list (list val * (option nat))) :=
1346+ result string (list (val * list val * (option nat))) :=
13281347 fault_ptes ←
13291348 for lvl in enum Level do
13301349 get_invalid_ptes_with_inv_time_by_lvl ts init mem tid tlb time lvl va asid ttbr
@@ -1339,25 +1358,27 @@ Module TLB.
13391358 | Some _, None => true
13401359 end .
13411360
1342- Definition is_new_entry (path : list val) (ti_new : option nat)
1343- (entries : list (list val * nat * option nat)) : bool :=
1361+ Definition is_new_entry (val_ttbr : val) ( path : list val) (ti_new : option nat)
1362+ (entries : list (val * list val * nat * option nat)) : bool :=
13441363 forallb
1345- (λ '(p, t, ti),
1346- negb(path =? p) || invalidation_time_lt ti ti_new) entries.
1364+ (λ '(vt, p, t, ti),
1365+ negb(val_ttbr =? vt)
1366+ || negb(path =? p)
1367+ || invalidation_time_lt ti ti_new) entries.
13471368
13481369 (* Snapshots are sorted in the descending order of [trans_time].
13491370 Thus, we do not have to use [trans_time] to check the interval *)
13501371 Definition get_valid_entries_from_snapshots (snapshots : list (t * nat))
13511372 (mem : Memory.t)
13521373 (tid : nat)
13531374 (va : bv 64) (asid : bv 16) :
1354- result string (list (list val * nat * option nat)) :=
1375+ result string (list (val * list val * nat * option nat)) :=
13551376 foldrM (λ '(tlb, trans_time) entries,
13561377 candidates ← TLB.lookup mem tid tlb trans_time va asid;
13571378 let new :=
1358- omap (λ '(path, ti_opt),
1359- if decide (is_new_entry path ti_opt entries) then
1360- Some (path, trans_time, ti_opt)
1379+ omap (λ '(val_ttbr, path, ti_opt),
1380+ if (is_new_entry val_ttbr path ti_opt entries) then
1381+ Some (val_ttbr, path, trans_time, ti_opt)
13611382 else None
13621383 ) candidates in
13631384 mret (new ++ entries)
@@ -1369,16 +1390,16 @@ Module TLB.
13691390 (mem : Memory.t)
13701391 (tid : nat) (is_ets2 : bool)
13711392 (va : bv 64) (asid : bv 16) (ttbr : reg) :
1372- result string (list (list val * nat * option nat)) :=
1393+ result string (list (val * list val * nat * option nat)) :=
13731394 foldrM (λ '(tlb, trans_time) entries,
13741395 if decide (is_ets2 ∧ trans_time < ts.(TState.vwr) ⊔ ts.(TState.vrd)) then
13751396 mret entries
13761397 else
13771398 candidates ← TLB.get_invalid_ptes_with_inv_time ts init mem tid tlb trans_time va asid ttbr;
13781399 let new :=
1379- omap (λ '(path, ti_opt),
1380- if decide (is_new_entry path ti_opt entries) then
1381- Some (path, trans_time, ti_opt)
1400+ omap (λ '(val_ttbr, path, ti_opt),
1401+ if decide (is_new_entry val_ttbr path ti_opt entries) then
1402+ Some (val_ttbr, path, trans_time, ti_opt)
13821403 else None
13831404 ) candidates in
13841405 mret (new ++ entries)
@@ -1399,7 +1420,8 @@ Module IIS.
13991420 make {
14001421 va : bv 36;
14011422 time : nat;
1402- remaining : list (bv 64); (* NOTE: translation memory read - ptes *)
1423+ root : option {ttbr : reg & reg_type ttbr};
1424+ remaining : list (bv 64);
14031425 invalidation : option nat
14041426 }.
14051427
@@ -1478,26 +1500,50 @@ Definition read_pte (vaddr : view) :
14781500 mset fst $ TState.update TState.vspec vpost;;
14791501 mret (vpost, val).
14801502
1503+ Definition run_reg_general_read (reg : reg) (racc : reg_acc) :
1504+ Exec.t (TState.t * IIS.t) string (reg_type reg * view) :=
1505+ ts ← mget fst;
1506+ if decide (reg ∈ relaxed_regs) then
1507+ if decide (is_Some racc)
1508+ then othrow
1509+ ("Register " ++ pretty reg ++ " unmapped on direct read")%string
1510+ $ TState.read_sreg_direct ts reg
1511+ else
1512+ valvs ← othrow
1513+ ("Register " ++ pretty reg ++ " unmapped on indirect read")%string
1514+ $ TState.read_sreg_indirect ts reg;
1515+ mchoosel valvs
1516+ else
1517+ othrow
1518+ ("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1519+ $ TState.read_reg ts reg.
1520+
1521+ Definition run_reg_trans_read (reg : reg) (racc : reg_acc)
1522+ (trs : IIS.TransRes.t) :
1523+ Exec.t TState.t string (reg_type reg * view) :=
1524+ guard_or "Translation read during the translation should be implicit"
1525+ (¬ (is_Some racc));;
1526+ root ← othrow "Could not find the translation root: error in translation assumptions"
1527+ (trs.(IIS.TransRes.root));
1528+ if decide (projT1 root = reg) is left eq then
1529+ mret (ctrans eq (projT2 root), 0%nat)
1530+ else
1531+ ts ← mGet;
1532+ othrow
1533+ ("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1534+ $ TState.read_reg ts reg.
1535+
14811536(** Run a RegRead outcome.
14821537 Returns the register value based on the type of register and the access type. *)
14831538Definition run_reg_read (reg : reg) (racc : reg_acc) :
14841539 Exec.t (TState.t * IIS.t) string (reg_type reg) :=
1485- ts ← mget fst;
14861540 '(val, view) ←
1487- (if decide (reg ∈ relaxed_regs) then
1488- if decide (is_Some racc)
1489- then othrow
1490- ("Register " ++ pretty reg ++ " unmapped on direct read")%string
1491- $ TState.read_sreg_direct ts reg
1492- else
1493- valvs ← othrow
1494- ("Register " ++ pretty reg ++ " unmapped on indirect read")%string
1495- $ TState.read_sreg_indirect ts reg;
1496- mchoosel valvs
1541+ (* Check if the register is read during the translation *)
1542+ iis ← mget snd;
1543+ if iis.(IIS.trs) is Some trs then
1544+ Exec.liftSt fst $ run_reg_trans_read reg racc trs
14971545 else
1498- othrow
1499- ("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1500- $ TState.read_reg ts reg);
1546+ run_reg_general_read reg racc;
15011547 mset snd $ IIS.add view;;
15021548 mret val.
15031549
@@ -1781,6 +1827,7 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
17811827 (* lookup (successful results or faults) *)
17821828 let asid := trans_start.(TranslationStartInfo_asid) in
17831829 let va : bv 64 := trans_start.(TranslationStartInfo_va) in
1830+
17841831 trans_res ←
17851832 if decide (va_in_range va) then
17861833 ttbr ← mlift $ ttbr_of_regime va trans_start.(TranslationStartInfo_regime);
@@ -1791,15 +1838,25 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
17911838 invalid_entries ← mlift $
17921839 TLB.get_invalid_entries_from_snapshots snapshots ts init mem tid is_ets2 va asid ttbr;
17931840 (* update IIS with either a valid translation result or a fault *)
1794- let valid_trs :=
1795- map (λ '(path, t, ti),
1796- IIS.TransRes.make (va_to_vpn va) t path ti) valid_entries in
1797- let invalid_trs :=
1798- map (λ '(path, t, ti),
1799- IIS.TransRes.make (va_to_vpn va) t path ti) invalid_entries in
1841+ valid_trs ←
1842+ for (val_ttbr, path, t, ti) in valid_entries do
1843+ val_ttbr ← othrow
1844+ "TTBR value type does not match with the value from the translation"
1845+ (val_to_regval ttbr val_ttbr);
1846+ let root := (Some (existT ttbr val_ttbr)) in
1847+ mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1848+ end ;
1849+ invalid_trs ←
1850+ for (val_ttbr, path, t, ti) in invalid_entries do
1851+ val_ttbr ← othrow
1852+ "TTBR value type does not match with the value from the translation"
1853+ (val_to_regval ttbr val_ttbr);
1854+ let root := (Some (existT ttbr val_ttbr)) in
1855+ mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1856+ end ;
18001857 mchoosel (valid_trs ++ invalid_trs)
18011858 else
1802- mret $ IIS.TransRes.make (va_to_vpn va) vpre_t [] None;
1859+ mret $ IIS.TransRes.make (va_to_vpn va) vpre_t None [] None;
18031860 mset PPState.iis $ IIS.set_trs trans_res.
18041861
18051862Definition read_fault_vpre (is_acq : bool)
0 commit comments