-/* $OpenBSD: machdep.c,v 1.25 2018/01/10 23:27:18 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.26 2018/01/12 14:52:55 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
*
EFI_MEMORY_DESCRIPTOR *mmap;
+void remap_efi_runtime(EFI_PHYSICAL_ADDRESS);
+
void collect_kernel_args(char *);
void process_kernel_args(void);
process_kernel_args();
- // XXX
- paddr_t pmap_steal_avail(size_t size, int align, void **kva);
-
void _start(void);
long kernbase = (long)&_start & ~0x00fff;
arm64_a4x_bs_tag._space_map = map_a4x_func_save;
/* Remap EFI runtime. */
- if (mmap_start != 0 && system_table != 0) {
- EFI_SYSTEM_TABLE *st = (EFI_SYSTEM_TABLE *)system_table;
- EFI_RUNTIME_SERVICES *rs;
- EFI_STATUS status;
- EFI_MEMORY_DESCRIPTOR *src;
- EFI_MEMORY_DESCRIPTOR *dst;
- EFI_PHYSICAL_ADDRESS phys_start = ~0ULL;
- EFI_VIRTUAL_ADDRESS virt_start;
- vsize_t space;
- int i, count = 0;
- paddr_t pa;
-
- /*
- * Pick a random address somewhere in the lower half
- * of the usable virtual address space.
- */
- space = 3 * (VM_MAX_ADDRESS - VM_MIN_ADDRESS) / 4;
- virt_start = VM_MIN_ADDRESS +
- ((vsize_t)arc4random_uniform(space >> PAGE_SHIFT) << PAGE_SHIFT);
-
- /* Make sure the EFI system table is mapped. */
- pmap_map_early(system_table, sizeof(EFI_SYSTEM_TABLE));
- rs = st->RuntimeServices;
-
- /* Make sure memory for EFI runtime services is mapped. */
- src = mmap;
- for (i = 0; i < mmap_size / mmap_desc_size; i++) {
- if (src->Attribute & EFI_MEMORY_RUNTIME) {
- pmap_map_early(src->PhysicalStart,
- src->NumberOfPages * PAGE_SIZE);
- if (phys_start > src->PhysicalStart)
- phys_start = src->PhysicalStart;
- count++;
- }
- src = NextMemoryDescriptor(src, mmap_desc_size);
- }
-
- /* Allocate memory descriptors for new mappings. */
- pa = pmap_steal_avail(count * mmap_desc_size,
- mmap_desc_size, NULL);
- memset((void *)pa, 0, count * mmap_desc_size);
-
- src = mmap;
- dst = (EFI_MEMORY_DESCRIPTOR *)pa;
- for (i = 0; i < mmap_size / mmap_desc_size; i++) {
- if (src->Attribute & EFI_MEMORY_RUNTIME) {
- src->VirtualStart = virt_start +
- (src->PhysicalStart - phys_start);
- memcpy(dst, src, mmap_desc_size);
- dst = NextMemoryDescriptor(dst, mmap_desc_size);
- }
- src = NextMemoryDescriptor(src, mmap_desc_size);
- }
-
- /* Install new mappings. */
- dst = (EFI_MEMORY_DESCRIPTOR *)pa;
- status = rs->SetVirtualAddressMap(count * mmap_desc_size,
- mmap_desc_size, mmap_desc_ver, dst);
- if (status != EFI_SUCCESS)
- printf("SetVirtualAddressMap failed: %lu\n", status);
- }
+ if (mmap_start != 0 && system_table != 0)
+ remap_efi_runtime(system_table);
/* XXX */
pmap_avail_fixup();
splraise(IPL_IPI);
}
+void
+remap_efi_runtime(EFI_PHYSICAL_ADDRESS system_table)
+{
+ EFI_SYSTEM_TABLE *st = (EFI_SYSTEM_TABLE *)system_table;
+ EFI_RUNTIME_SERVICES *rs;
+ EFI_STATUS status;
+ EFI_MEMORY_DESCRIPTOR *src;
+ EFI_MEMORY_DESCRIPTOR *dst;
+ EFI_PHYSICAL_ADDRESS phys_start = ~0ULL;
+ EFI_PHYSICAL_ADDRESS phys_end = 0;
+ EFI_VIRTUAL_ADDRESS virt_start;
+ vsize_t space;
+ int i, count = 0;
+ paddr_t pa;
+
+ /*
+ * Pick a random address somewhere in the lower half of the
+ * usable virtual address space.
+ */
+ space = 3 * (VM_MAX_ADDRESS - VM_MIN_ADDRESS) / 4;
+ virt_start = VM_MIN_ADDRESS +
+ ((vsize_t)arc4random_uniform(space >> PAGE_SHIFT) << PAGE_SHIFT);
+
+ /* Make sure the EFI system table is mapped. */
+ pmap_map_early(system_table, sizeof(EFI_SYSTEM_TABLE));
+ rs = st->RuntimeServices;
+
+ /*
+ * Make sure memory for EFI runtime services is mapped. We
+ * only map normal memory at this point and pray that the
+ * SetVirtualAddressMap call doesn't need anything else.
+ */
+ src = mmap;
+ for (i = 0; i < mmap_size / mmap_desc_size; i++) {
+ if (src->Attribute & EFI_MEMORY_RUNTIME) {
+ if (src->Attribute & EFI_MEMORY_WB) {
+ pmap_map_early(src->PhysicalStart,
+ src->NumberOfPages * PAGE_SIZE);
+ phys_start = MIN(phys_start,
+ src->PhysicalStart);
+ phys_end = MAX(phys_end, src->PhysicalStart +
+ src->NumberOfPages * PAGE_SIZE);
+ }
+ count++;
+ }
+ src = NextMemoryDescriptor(src, mmap_desc_size);
+ }
+
+ /* Allocate memory descriptors for new mappings. */
+ pa = pmap_steal_avail(count * mmap_desc_size,
+ mmap_desc_size, NULL);
+ memset((void *)pa, 0, count * mmap_desc_size);
+
+ /*
+ * Establish new mappings. Apparently some EFI code relies on
+ * the offset between code and data remaining the same so pick
+ * virtual addresses for normal memory that meet that
+ * constraint. Other mappings are simply tagged to the end of
+ * the last normal memory mapping.
+ */
+ src = mmap;
+ dst = (EFI_MEMORY_DESCRIPTOR *)pa;
+ for (i = 0; i < mmap_size / mmap_desc_size; i++) {
+ if (src->Attribute & EFI_MEMORY_RUNTIME) {
+ if (src->Attribute & EFI_MEMORY_WB) {
+ src->VirtualStart = virt_start +
+ (src->PhysicalStart - phys_start);
+ } else {
+ src->VirtualStart = virt_start +
+ (phys_end - phys_start);
+ phys_end += src->NumberOfPages * PAGE_SIZE;
+ }
+ memcpy(dst, src, mmap_desc_size);
+ dst = NextMemoryDescriptor(dst, mmap_desc_size);
+ }
+ src = NextMemoryDescriptor(src, mmap_desc_size);
+ }
+
+ /* Install new mappings. */
+ dst = (EFI_MEMORY_DESCRIPTOR *)pa;
+ status = rs->SetVirtualAddressMap(count * mmap_desc_size,
+ mmap_desc_size, mmap_desc_ver, dst);
+ if (status != EFI_SUCCESS)
+ printf("SetVirtualAddressMap failed: %lu\n", status);
+}
+
int comcnspeed = B115200;
char bootargs[MAX_BOOT_STRING];