Use EFI memory map to determine attributes for Acpi mappings on arm64.
AcpiOsMapMemory is used for device memory when e.g. an _INI method wants to access physical memory, however, aarch64 pmap_mapbios is hardcoded to writeback. Search for the correct memory type to use in pmap_mapbios. Submitted by: Greg V <greg_unrelenting.technology> Differential Revision: https://reviews.freebsd.org/D25201
This commit is contained in:
parent
e99ce3eac5
commit
23e42a83c1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362726
@ -120,6 +120,7 @@ int has_pan;
|
|||||||
* passed into the kernel and used by the EFI code to call runtime services.
|
* passed into the kernel and used by the EFI code to call runtime services.
|
||||||
*/
|
*/
|
||||||
vm_paddr_t efi_systbl_phys;
|
vm_paddr_t efi_systbl_phys;
|
||||||
|
static struct efi_map_header *efihdr;
|
||||||
|
|
||||||
/* pagezero_* implementations are provided in support.S */
|
/* pagezero_* implementations are provided in support.S */
|
||||||
void pagezero_simple(void *);
|
void pagezero_simple(void *);
|
||||||
@ -1071,11 +1072,52 @@ cache_setup(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
memory_mapping_mode(vm_paddr_t pa)
|
||||||
|
{
|
||||||
|
struct efi_md *map, *p;
|
||||||
|
size_t efisz;
|
||||||
|
int ndesc, i;
|
||||||
|
|
||||||
|
if (efihdr == NULL)
|
||||||
|
return (VM_MEMATTR_WRITE_BACK);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory map data provided by UEFI via the GetMemoryMap
|
||||||
|
* Boot Services API.
|
||||||
|
*/
|
||||||
|
efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
|
||||||
|
map = (struct efi_md *)((uint8_t *)efihdr + efisz);
|
||||||
|
|
||||||
|
if (efihdr->descriptor_size == 0)
|
||||||
|
return (VM_MEMATTR_WRITE_BACK);
|
||||||
|
ndesc = efihdr->memory_size / efihdr->descriptor_size;
|
||||||
|
|
||||||
|
for (i = 0, p = map; i < ndesc; i++,
|
||||||
|
p = efi_next_descriptor(p, efihdr->descriptor_size)) {
|
||||||
|
if (pa < p->md_phys ||
|
||||||
|
pa >= p->md_phys + p->md_pages * EFI_PAGE_SIZE)
|
||||||
|
continue;
|
||||||
|
if (p->md_type == EFI_MD_TYPE_IOMEM ||
|
||||||
|
p->md_type == EFI_MD_TYPE_IOPORT)
|
||||||
|
return (VM_MEMATTR_DEVICE);
|
||||||
|
else if ((p->md_attr & EFI_MD_ATTR_WB) != 0 ||
|
||||||
|
p->md_type == EFI_MD_TYPE_RECLAIM)
|
||||||
|
return (VM_MEMATTR_WRITE_BACK);
|
||||||
|
else if ((p->md_attr & EFI_MD_ATTR_WT) != 0)
|
||||||
|
return (VM_MEMATTR_WRITE_THROUGH);
|
||||||
|
else if ((p->md_attr & EFI_MD_ATTR_WC) != 0)
|
||||||
|
return (VM_MEMATTR_WRITE_COMBINING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (VM_MEMATTR_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initarm(struct arm64_bootparams *abp)
|
initarm(struct arm64_bootparams *abp)
|
||||||
{
|
{
|
||||||
struct efi_fb *efifb;
|
struct efi_fb *efifb;
|
||||||
struct efi_map_header *efihdr;
|
|
||||||
struct pcpu *pcpup;
|
struct pcpu *pcpup;
|
||||||
char *env;
|
char *env;
|
||||||
#ifdef FDT
|
#ifdef FDT
|
||||||
|
@ -5449,7 +5449,7 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t size)
|
|||||||
/* L3 table is linked */
|
/* L3 table is linked */
|
||||||
va = trunc_page(va);
|
va = trunc_page(va);
|
||||||
pa = trunc_page(pa);
|
pa = trunc_page(pa);
|
||||||
pmap_kenter(va, size, pa, VM_MEMATTR_WRITE_BACK);
|
pmap_kenter(va, size, pa, memory_mapping_mode(pa));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((void *)(va + offset));
|
return ((void *)(va + offset));
|
||||||
|
@ -56,6 +56,7 @@ vm_offset_t parse_boot_param(struct arm64_bootparams *abp);
|
|||||||
#ifdef FDT
|
#ifdef FDT
|
||||||
void parse_fdt_bootargs(void);
|
void parse_fdt_bootargs(void);
|
||||||
#endif
|
#endif
|
||||||
|
int memory_mapping_mode(vm_paddr_t pa);
|
||||||
extern void (*pagezero)(void *);
|
extern void (*pagezero)(void *);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
Loading…
Reference in New Issue
Block a user