+
+/*
+ * Read data from a physical address. Memory should not be cache inhibited.
+ */
+
+
+static unsigned int
+ml_phys_read_data( vm_offset_t paddr, int size )
+{
+ unsigned int result;
+ pt_entry_t save;
+ mp_disable_preemption();
+ if (*(pt_entry_t *) CM3)
+ panic("ml_phys_read_data: CMAP busy");
+
+ *(pt_entry_t *) CM3 = INTEL_PTE_VALID | (paddr & PG_FRAME) | INTEL_PTE_REF;
+ save = *(pt_entry_t *)CM3;
+ invlpg((u_int)CA3);
+
+
+ switch (size) {
+ unsigned char s1;
+ unsigned short s2;
+ case 1:
+ s1 = *(unsigned char *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK));
+ result = s1;
+ break;
+ case 2:
+ s2 = *(unsigned short *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK));
+ result = s2;
+ break;
+ case 4:
+ default:
+ result = *(unsigned int *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK));
+ break;
+ }
+
+ if (save != *(pt_entry_t *)CM3) panic("ml_phys_read_data CMAP changed");
+ *(pt_entry_t *) CM3 = 0;
+ mp_enable_preemption();
+ return result;
+}
+
+static unsigned long long
+ml_phys_read_long_long( vm_offset_t paddr )
+{
+ unsigned long long result;
+ pt_entry_t save;
+ mp_disable_preemption();
+ if (*(pt_entry_t *) CM3)
+ panic("ml_phys_read_data: CMAP busy");
+
+ *(pt_entry_t *) CM3 = INTEL_PTE_VALID | (paddr & PG_FRAME) | INTEL_PTE_REF;
+ save = *(pt_entry_t *)CM3;
+ invlpg((u_int)CA3);
+
+ result = *(unsigned long long *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK));
+
+ if (save != *(pt_entry_t *)CM3) panic("ml_phys_read_data CMAP changed");
+ *(pt_entry_t *) CM3 = 0;
+ mp_enable_preemption();
+ return result;
+}
+
+unsigned int ml_phys_read( vm_offset_t paddr)
+{
+ return ml_phys_read_data(paddr, 4);
+}
+
+unsigned int ml_phys_read_word(vm_offset_t paddr) {
+ return ml_phys_read_data(paddr, 4);
+}
+
+unsigned int ml_phys_read_64(addr64_t paddr64)
+{
+ return ml_phys_read_data(low32(paddr64), 4);
+}
+
+unsigned int ml_phys_read_word_64(addr64_t paddr64)
+{
+ return ml_phys_read_data(low32(paddr64), 4);
+}
+
+unsigned int ml_phys_read_half(vm_offset_t paddr)
+{
+ return ml_phys_read_data(paddr, 2);
+}
+
+unsigned int ml_phys_read_half_64(addr64_t paddr64)
+{
+ return ml_phys_read_data(low32(paddr64), 2);
+}
+
+unsigned int ml_phys_read_byte(vm_offset_t paddr)
+{
+ return ml_phys_read_data(paddr, 1);
+}
+
+unsigned int ml_phys_read_byte_64(addr64_t paddr64)
+{
+ return ml_phys_read_data(low32(paddr64), 1);
+}
+
+unsigned long long ml_phys_read_double(vm_offset_t paddr)
+{
+ return ml_phys_read_long_long(paddr);
+}
+
+unsigned long long ml_phys_read_double_64(addr64_t paddr)
+{
+ return ml_phys_read_long_long(low32(paddr));
+}
+
+
+/*
+ * Write data to a physical address. Memory should not be cache inhibited.
+ */
+
+static void
+ml_phys_write_data( vm_offset_t paddr, unsigned long data, int size )
+{
+ pt_entry_t save;
+ mp_disable_preemption();
+ if (*(pt_entry_t *) CM3)
+ panic("ml_phys_write_data: CMAP busy");
+
+ *(pt_entry_t *) CM3 = INTEL_PTE_VALID | INTEL_PTE_RW | (paddr & PG_FRAME) |
+ INTEL_PTE_REF | INTEL_PTE_MOD;
+ save = *(pt_entry_t *)CM3;
+ invlpg((u_int)CA3);
+
+ switch (size) {
+ case 1:
+ *(unsigned char *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK)) = (unsigned char)data;
+ break;
+ case 2:
+ *(unsigned short *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK)) = (unsigned short)data;
+ break;
+ case 4:
+ default:
+ *(unsigned int *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK)) = data;
+ break;
+ }
+
+ if (save != *(pt_entry_t *)CM3) panic("ml_phys_write_data CMAP changed");
+ *(pt_entry_t *) CM3 = 0;
+ mp_enable_preemption();
+}
+
+static void
+ml_phys_write_long_long( vm_offset_t paddr, unsigned long long data )
+{
+ pt_entry_t save;
+ mp_disable_preemption();
+ if (*(pt_entry_t *) CM3)
+ panic("ml_phys_write_data: CMAP busy");
+
+ *(pt_entry_t *) CM3 = INTEL_PTE_VALID | INTEL_PTE_RW | (paddr & PG_FRAME) |
+ INTEL_PTE_REF | INTEL_PTE_MOD;
+ save = *(pt_entry_t *)CM3;
+ invlpg((u_int)CA3);
+
+ *(unsigned long long *)((unsigned int)CA3 | (paddr & INTEL_OFFMASK)) = data;
+
+ if (save != *(pt_entry_t *)CM3) panic("ml_phys_write_data CMAP changed");
+ *(pt_entry_t *) CM3 = 0;
+ mp_enable_preemption();
+}
+
+void ml_phys_write_byte(vm_offset_t paddr, unsigned int data)
+{
+ ml_phys_write_data(paddr, data, 1);
+}
+
+void ml_phys_write_byte_64(addr64_t paddr, unsigned int data)
+{
+ ml_phys_write_data(low32(paddr), data, 1);
+}
+
+void ml_phys_write_half(vm_offset_t paddr, unsigned int data)
+{
+ ml_phys_write_data(paddr, data, 2);
+}
+
+void ml_phys_write_half_64(addr64_t paddr, unsigned int data)
+{
+ ml_phys_write_data(low32(paddr), data, 2);
+}
+
+void ml_phys_write(vm_offset_t paddr, unsigned int data)