Read an unsigned 48-bit value from memory via an effective address.
(rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86) → (mv flg value x86-new)
The effective address
Prior to the effective address translation, we check whether read access is allowed. The only case in which it is not allowed is when a read access is attempted on an execute-only code segment, in 32-bit mode. In 64-bit mode, the R bit of the code segment descriptor is ignored (see Atmel manual, Dec'17, Volume 2, Section 4.8.1).
Function:
(defun rme48$inline (proc-mode eff-addr seg-reg r-x check-alignment? x86) (declare (xargs :stobjs (x86))) (declare (type (integer 0 4) proc-mode) (type (signed-byte 64) eff-addr) (type (integer 0 5) seg-reg) (type (member :r :x) r-x)) (declare (xargs :guard (booleanp check-alignment?))) (b* (((when (and (/= proc-mode 0) (= seg-reg 1) (eq r-x :r) (b* ((attr (loghead 16 (seg-hidden-attri seg-reg x86))) (r (code-segment-descriptor-attributesbits->r attr))) (= r 0)))) (mv (list :execute-only-code-segment eff-addr) 0 x86)) ((mv flg lin-addr) (ea-to-la proc-mode eff-addr seg-reg 6 x86)) ((when flg) (mv flg 0 x86)) ((unless (or (not check-alignment?) (address-aligned-p lin-addr 6 nil))) (mv (list :unaligned-linear-address lin-addr) 0 x86))) (rml48 lin-addr r-x x86)))
Theorem:
(defthm return-type-of-rme48.value (implies (x86p x86) (b* (((mv ?flg acl2::?value ?x86-new) (rme48$inline proc-mode eff-addr seg-reg r-x check-alignment? x86))) (unsigned-byte-p 48 value))) :rule-classes :rewrite)
Theorem:
(defthm x86p-of-rme48.x86-new (implies (x86p x86) (b* (((mv ?flg acl2::?value ?x86-new) (rme48$inline proc-mode eff-addr seg-reg r-x check-alignment? x86))) (x86p x86-new))) :rule-classes :rewrite)
Theorem:
(defthm n48p-of-mv-nth-1-rme48 (unsigned-byte-p 48 (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) :rule-classes (:rewrite (:type-prescription :corollary (natp (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) :hints (("Goal" :in-theory '(unsigned-byte-p integer-range-p natp)))) (:linear :corollary (and (<= 0 (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (< (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)) 281474976710656)) :hints (("Goal" :in-theory '(unsigned-byte-p integer-range-p (:e expt)))))))
Theorem:
(defthm rme48-value-when-error (implies (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)) (equal (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)) 0)))
Theorem:
(defthm rme48-does-not-affect-state-in-app-view (implies (app-view x86) (equal (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)) x86)))
Theorem:
(defthm xr-rme48-state-app-view (implies (app-view x86) (equal (xr fld index (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (xr fld index x86))))
Theorem:
(defthm xr-rme48-state-sys-view (implies (and (not (app-view x86)) (not (equal fld :mem)) (not (equal fld :fault)) (not (equal fld :tlb)) (member-equal fld *x86-field-names-as-keywords*)) (equal (xr fld index (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (xr fld index x86))))
Theorem:
(defthm rme48-xw-app-view (implies (and (app-view x86) (not (equal fld :mem)) (not (equal fld :app-view)) (not (equal fld :seg-hidden-base)) (not (equal fld :seg-hidden-limit)) (not (equal fld :seg-hidden-attr)) (not (equal fld :seg-visible)) (not (equal fld :msr))) (and (equal (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86))) (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (equal (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86))) (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))))))
Theorem:
(defthm rme48-xw-sys-view (implies (and (not (app-view x86)) (not (equal fld :fault)) (not (equal fld :seg-visible)) (not (equal fld :seg-hidden-base)) (not (equal fld :seg-hidden-limit)) (not (equal fld :seg-hidden-attr)) (not (equal fld :mem)) (not (equal fld :ctr)) (not (equal fld :msr)) (not (equal fld :rflags)) (not (equal fld :app-view)) (not (equal fld :tlb)) (not (equal fld :marking-view)) (not (equal fld :implicit-supervisor-access)) (member-equal fld *x86-field-names-as-keywords*)) (and (equal (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86))) (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (equal (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86))) (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (equal (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw fld index value x86))) (xw fld index value (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)))))))
Theorem:
(defthm rme48-xw-sys-view-rflags-not-ac (implies (and (not (app-view x86)) (equal (rflagsbits->ac value) (rflagsbits->ac (rflags x86)))) (and (equal (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86))) (mv-nth 0 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (equal (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86))) (mv-nth 1 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86))) (equal (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? (xw :rflags nil value x86))) (xw :rflags nil value (mv-nth 2 (rme48 proc-mode eff-addr seg-reg r-x check-alignment? x86)))))))
Theorem:
(defthm rme48-when-64-bit-modep-and-not-fs/gs (implies (and (not (equal seg-reg 4)) (not (equal seg-reg 5)) (canonical-address-p eff-addr) (or (not check-alignment?) (address-aligned-p eff-addr 6 nil))) (equal (rme48 0 eff-addr seg-reg r-x check-alignment? x86) (rml48 eff-addr r-x x86))))
Theorem:
(defthm rme48-unaligned-when-64-bit-modep-and-not-fs/gs (implies (and (not (equal seg-reg 4)) (not (equal seg-reg 5)) (not (or (not check-alignment?) (address-aligned-p eff-addr 6 nil))) (canonical-address-p eff-addr)) (equal (rme48 0 eff-addr seg-reg r-x check-alignment? x86) (list (list :unaligned-linear-address eff-addr) 0 x86))))
Theorem:
(defthm rme48-when-64-bit-modep-and-fs/gs (implies (or (equal seg-reg 4) (equal seg-reg 5)) (equal (rme48 0 eff-addr seg-reg r-x check-alignment? x86) (b* (((mv flg lin-addr) (b* (((mv base & &) (segment-base-and-bounds 0 seg-reg x86)) (lin-addr (i64 (+ base (n64 eff-addr))))) (if (canonical-address-p lin-addr) (mv nil lin-addr) (mv (list :non-canonical-address lin-addr) 0)))) ((when flg) (mv flg 0 x86)) ((unless (or (not check-alignment?) (address-aligned-p lin-addr 6 nil))) (mv (list :unaligned-linear-address lin-addr) 0 x86))) (rml48 lin-addr r-x x86)))))