acpi_status acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void **virt) { #ifdef CONFIG_ACPI_EFI if (EFI_MEMORY_WB & efi_mem_attributes(phys)) { *virt = phys_to_virt(phys); } else { *virt = ioremap(phys, size); } #else if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); return AE_BAD_PARAMETER; } /* * ioremap checks to ensure this is in reserved space */ *virt = ioremap((unsigned long) phys, size); #endif if (!*virt) return AE_NO_MEMORY; return AE_OK; }
/* * Architectures vary in how they handle caching for addresses * outside of main memory. * */ static inline int uncached_access(struct file *file, unsigned long addr) { #if defined(__i386__) /* * On the PPro and successors, the MTRRs are used to set * memory types for physical addresses outside main memory, * so blindly setting PCD or PWT on those pages is wrong. * For Pentiums and earlier, the surround logic should disable * caching for the high addresses through the KEN pin, but * we maintain the tradition of paranoia in this code. */ if (file->f_flags & O_SYNC) return 1; return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) ) && addr >= __pa(high_memory); #elif defined(__x86_64__) /* * This is broken because it can generate memory type aliases, * which can cause cache corruptions * But it is only available for root and we have to be bug-to-bug * compatible with i386. */ if (file->f_flags & O_SYNC) return 1; /* same behaviour as i386. PAT always set to cached and MTRRs control the caching behaviour. Hopefully a full PAT implementation will fix that soon. */ return 0; #elif defined(CONFIG_IA64) /* * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. */ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); #elif defined(CONFIG_PPC64) /* On PPC64, we always do non-cacheable access to the IO hole and * cacheable elsewhere. Cache paradox can checkstop the CPU and * the high_memory heuristic below is wrong on machines with memory * above the IO hole... Ah, and of course, XFree86 doesn't pass * O_SYNC when mapping us to tap IO space. Surprised ? */ return !page_is_ram(addr >> PAGE_SHIFT); #else /* * Accessing memory above the top the kernel knows about or through a file pointer * that was marked O_SYNC will be done non-cached. */ if (file->f_flags & O_SYNC) return 1; return addr >= __pa(high_memory); #endif }
acpi_status acpi_os_read_memory( acpi_physical_address phys_addr, u32 *value, u32 width) { u32 dummy; void *virt_addr; #ifdef CONFIG_ACPI_EFI int iomem = 0; if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { virt_addr = phys_to_virt(phys_addr); } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } #else virt_addr = phys_to_virt(phys_addr); #endif if (!value) value = &dummy; switch (width) { case 8: *(u8*) value = *(u8*) virt_addr; break; case 16: *(u16*) value = *(u16*) virt_addr; break; case 32: *(u32*) value = *(u32*) virt_addr; break; default: BUG(); } #ifdef CONFIG_ACPI_EFI if (iomem) iounmap(virt_addr); #endif return AE_OK; }
acpi_status acpi_os_read_memory( acpi_physical_address phys_addr, u32 *value, u32 width) { u32 dummy; void __iomem *virt_addr; int iomem = 0; if (efi_enabled) { if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { /* HACK ALERT! We can use readb/w/l on real memory too.. */ virt_addr = (void __iomem *) phys_to_virt(phys_addr); } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } } else virt_addr = (void __iomem *) phys_to_virt(phys_addr); if (!value) value = &dummy; switch (width) { case 8: *(u8*) value = readb(virt_addr); break; case 16: *(u16*) value = readw(virt_addr); break; case 32: *(u32*) value = readl(virt_addr); break; default: BUG(); } if (efi_enabled) { if (iomem) iounmap(virt_addr); } return AE_OK; }
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) { /* * According to "Table 8 Map: EFI memory types to AArch64 memory * types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is * mapped to a corresponding MAIR attribute encoding. * The EFI memory attribute advises all possible capabilities * of a memory region. We use the most efficient capability. */ u64 attr; attr = efi_mem_attributes(addr); if (attr & EFI_MEMORY_WB) return PAGE_KERNEL; if (attr & EFI_MEMORY_WT) return __pgprot(PROT_NORMAL_WT); if (attr & EFI_MEMORY_WC) return __pgprot(PROT_NORMAL_NC); return __pgprot(PROT_DEVICE_nGnRnE); }
acpi_status acpi_os_write_memory( acpi_physical_address phys_addr, u32 value, u32 width) { void __iomem *virt_addr; int iomem = 0; if (efi_enabled) { if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { /* HACK ALERT! We can use writeb/w/l on real memory too */ virt_addr = (void __iomem *) phys_to_virt(phys_addr); } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } } else virt_addr = (void __iomem *) phys_to_virt(phys_addr); switch (width) { case 8: writeb(value, virt_addr); break; case 16: writew(value, virt_addr); break; case 32: writel(value, virt_addr); break; default: BUG(); } if (iomem) iounmap(virt_addr); return AE_OK; }
acpi_status acpi_os_write_memory( acpi_physical_address phys_addr, u32 value, u32 width) { void *virt_addr; int iomem = 0; if (efi_enabled) { if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { virt_addr = phys_to_virt(phys_addr); } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } } else virt_addr = phys_to_virt(phys_addr); switch (width) { case 8: *(u8*) virt_addr = value; break; case 16: *(u16*) virt_addr = value; break; case 32: *(u32*) virt_addr = value; break; default: BUG(); } if (iomem) iounmap(virt_addr); return AE_OK; }