mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-11 09:50:12 +00:00
Allow us to read the physmap data into our own array and use this to build
the DMAP region on arm64. We already have the needed information to build these tables, we just need to extract it. This significantly simplifies the code. Obtained from: ABT Systems Ltd Sponsored by: Turing Robotic Industries
This commit is contained in:
parent
bb8f162363
commit
9f1a80706c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=334162
@ -375,6 +375,13 @@ void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
|
||||
excnt = insert_region(exregions, excnt, pa, sz, exflags);
|
||||
}
|
||||
|
||||
size_t
|
||||
arm_physmem_avail(vm_paddr_t *avail, size_t maxavail)
|
||||
{
|
||||
|
||||
return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, NULL, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Process all the regions added earlier into the global avail lists.
|
||||
*
|
||||
|
@ -56,6 +56,7 @@ extern vm_paddr_t arm_physmem_kernaddr;
|
||||
|
||||
void arm_physmem_hardware_region(uint64_t pa, uint64_t sz);
|
||||
void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t flags);
|
||||
size_t arm_physmem_avail(vm_paddr_t *avail, size_t maxavail);
|
||||
void arm_physmem_init_kernel_globals(void);
|
||||
void arm_physmem_print_tables(void);
|
||||
|
||||
|
@ -106,10 +106,6 @@ static struct trapframe proc0_tf;
|
||||
int early_boot = 1;
|
||||
int cold = 1;
|
||||
|
||||
#define PHYSMAP_SIZE (2 * (VM_PHYSSEG_MAX - 1))
|
||||
vm_paddr_t physmap[PHYSMAP_SIZE];
|
||||
u_int physmap_idx;
|
||||
|
||||
struct kva_md_info kmi;
|
||||
|
||||
int64_t dcache_line_size; /* The minimum D cache line size */
|
||||
@ -724,88 +720,8 @@ typedef struct {
|
||||
uint64_t attr;
|
||||
} EFI_MEMORY_DESCRIPTOR;
|
||||
|
||||
static int
|
||||
add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
|
||||
u_int *physmap_idxp)
|
||||
{
|
||||
u_int i, insert_idx, _physmap_idx;
|
||||
|
||||
_physmap_idx = *physmap_idxp;
|
||||
|
||||
if (length == 0)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Find insertion point while checking for overlap. Start off by
|
||||
* assuming the new entry will be added to the end.
|
||||
*/
|
||||
insert_idx = _physmap_idx;
|
||||
for (i = 0; i <= _physmap_idx; i += 2) {
|
||||
if (base < physmap[i + 1]) {
|
||||
if (base + length <= physmap[i]) {
|
||||
insert_idx = i;
|
||||
break;
|
||||
}
|
||||
if (boothowto & RB_VERBOSE)
|
||||
printf(
|
||||
"Overlapping memory regions, ignoring second region\n");
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
/* See if we can prepend to the next entry. */
|
||||
if (insert_idx <= _physmap_idx &&
|
||||
base + length == physmap[insert_idx]) {
|
||||
physmap[insert_idx] = base;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* See if we can append to the previous entry. */
|
||||
if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
|
||||
physmap[insert_idx - 1] += length;
|
||||
return (1);
|
||||
}
|
||||
|
||||
_physmap_idx += 2;
|
||||
*physmap_idxp = _physmap_idx;
|
||||
if (_physmap_idx == PHYSMAP_SIZE) {
|
||||
printf(
|
||||
"Too many segments in the physical address map, giving up\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the last 'N' entries down to make room for the new
|
||||
* entry if needed.
|
||||
*/
|
||||
for (i = _physmap_idx; i > insert_idx; i -= 2) {
|
||||
physmap[i] = physmap[i - 2];
|
||||
physmap[i + 1] = physmap[i - 1];
|
||||
}
|
||||
|
||||
/* Insert the new entry. */
|
||||
physmap[insert_idx] = base;
|
||||
physmap[insert_idx + 1] = base + length;
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef FDT
|
||||
static void
|
||||
add_fdt_mem_regions(struct mem_region *mr, int mrcnt, vm_paddr_t *physmap,
|
||||
u_int *physmap_idxp)
|
||||
{
|
||||
|
||||
for (int i = 0; i < mrcnt; i++) {
|
||||
if (!add_physmap_entry(mr[i].mr_start, mr[i].mr_size, physmap,
|
||||
physmap_idxp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
|
||||
u_int *physmap_idxp)
|
||||
add_efi_map_entries(struct efi_map_header *efihdr)
|
||||
{
|
||||
struct efi_md *map, *p;
|
||||
const char *type;
|
||||
@ -897,9 +813,6 @@ add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
|
||||
|
||||
arm_physmem_hardware_region(p->md_phys,
|
||||
p->md_pages * PAGE_SIZE);
|
||||
if (!add_physmap_entry(p->md_phys, (p->md_pages * PAGE_SIZE),
|
||||
physmap, physmap_idxp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1048,19 +961,16 @@ initarm(struct arm64_bootparams *abp)
|
||||
lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
|
||||
|
||||
/* Load the physical memory ranges */
|
||||
physmap_idx = 0;
|
||||
efihdr = (struct efi_map_header *)preload_search_info(kmdp,
|
||||
MODINFO_METADATA | MODINFOMD_EFI_MAP);
|
||||
if (efihdr != NULL)
|
||||
add_efi_map_entries(efihdr, physmap, &physmap_idx);
|
||||
add_efi_map_entries(efihdr);
|
||||
#ifdef FDT
|
||||
else {
|
||||
/* Grab physical memory regions information from device tree. */
|
||||
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz,
|
||||
NULL) != 0)
|
||||
panic("Cannot get physical memory regions");
|
||||
add_fdt_mem_regions(mem_regions, mem_regions_sz, physmap,
|
||||
&physmap_idx);
|
||||
arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
|
||||
}
|
||||
if (fdt_get_reserved_mem(mem_regions, &mem_regions_sz) == 0)
|
||||
|
@ -259,6 +259,10 @@ CTASSERT((DMAP_MAX_ADDRESS & ~L0_OFFSET) == DMAP_MAX_ADDRESS);
|
||||
#define DMAP_TABLES ((DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS) >> L0_SHIFT)
|
||||
extern pt_entry_t pagetable_dmap[];
|
||||
|
||||
#define PHYSMAP_SIZE (2 * (VM_PHYSSEG_MAX - 1))
|
||||
static vm_paddr_t physmap[PHYSMAP_SIZE];
|
||||
static u_int physmap_idx;
|
||||
|
||||
static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
|
||||
|
||||
static int superpages_enabled = 1;
|
||||
@ -709,6 +713,9 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_paddr_t kernstart,
|
||||
/* Assume the address we were loaded to is a valid physical address */
|
||||
min_pa = max_pa = KERNBASE - kern_delta;
|
||||
|
||||
physmap_idx = arm_physmem_avail(physmap, nitems(physmap));
|
||||
physmap_idx /= 2;
|
||||
|
||||
/*
|
||||
* Find the minimum physical address. physmap is sorted,
|
||||
* but may contain empty ranges.
|
||||
|
Loading…
Reference in New Issue
Block a user