[haiku-commits] BRANCH jessicah-github.efi.master [ea64a5d823a6] in src/system/boot: platform/efi loader

  • From: jessicah-github.efi.master <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 16 Sep 2015 03:46:58 +0200 (CEST)

added 3 changesets to branch 'refs/remotes/jessicah-github/efi.master'
old head: fc29aea9b31cb4617d978d4a6020d67e30184841
new head: ea64a5d823a66754bab409ed99a90eaadffa79cf
overview: https://github.com/jessicah/haiku/compare/fc29aea9b31c...ea64a5d823a6

----------------------------------------------------------------------------

288fc3f4e422: UEFI: see if we actually need to use AllocatePages.

Doesn't seem to be helping with boot issues at all,
however :(

86a94f294c06: Lots of debugging: delete this commit later

ea64a5d823a6: UEFI: don't do all the things!

- No SMP support
- Don't create virtual mappings for UEFI boot/runtime services
- Don't call UEFI SetVirtualAddressMap()

This at least gets us booting on some actual hardware. The
booted system is quite unstable, however :(

[ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ]

----------------------------------------------------------------------------

9 files changed, 137 insertions(+), 47 deletions(-)
src/system/boot/loader/main.cpp | 6 ++-
src/system/boot/loader/vfs.cpp | 25 +++++++++++--
src/system/boot/platform/efi/acpi.cpp | 10 ++---
src/system/boot/platform/efi/devices.cpp | 55 +++++++++++++++++++++++-----
src/system/boot/platform/efi/mmu.cpp | 39 +++++++++++++++-----
src/system/boot/platform/efi/mmu.h | 2 +-
src/system/boot/platform/efi/serial.cpp | 3 ++
src/system/boot/platform/efi/smp.cpp | 36 +++++++++++-------
src/system/boot/platform/efi/start.cpp | 8 ++--

############################################################################

Commit: 288fc3f4e42279a3a92f368edb142549cd717f77
Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date: Sun Sep 13 01:14:21 2015 UTC

UEFI: see if we actually need to use AllocatePages.

Doesn't seem to be helping with boot issues at all,
however :(

----------------------------------------------------------------------------

diff --git a/src/system/boot/platform/efi/acpi.cpp
b/src/system/boot/platform/efi/acpi.cpp
index 200e2c8..8a3f763 100644
--- a/src/system/boot/platform/efi/acpi.cpp
+++ b/src/system/boot/platform/efi/acpi.cpp
@@ -96,7 +96,7 @@ acpi_check_rsdt(acpi_rsdp* rsdp)
if (rsdp->revision > 0) {
length = rsdp->xsdt_length;
rsdt = (acpi_descriptor_header*)mmu_map_physical_memory(
- (uint32)rsdp->xsdt_address, rsdp->xsdt_length,
kDefaultPageFlags);
+ (uint32)rsdp->xsdt_address, rsdp->xsdt_length,
EfiACPIReclaimMemory);
if (rsdt != NULL
&& strncmp(rsdt->signature, ACPI_XSDT_SIGNATURE, 4) !=
0) {
mmu_free(rsdt, rsdp->xsdt_length);
@@ -112,7 +112,7 @@ acpi_check_rsdt(acpi_rsdp* rsdp)
// map and validate the root system description table
rsdt = (acpi_descriptor_header*)mmu_map_physical_memory(
rsdp->rsdt_address, sizeof(acpi_descriptor_header),
- kDefaultPageFlags);
+ EfiACPIReclaimMemory);
if (rsdt == NULL) {
TRACE(("acpi: couldn't map rsdt header\n"));
return B_ERROR;
@@ -129,7 +129,7 @@ acpi_check_rsdt(acpi_rsdp* rsdp)
TRACE(("acpi: rsdt length: %u\n", length));
mmu_free(rsdt, sizeof(acpi_descriptor_header));
rsdt = (acpi_descriptor_header*)mmu_map_physical_memory(
- rsdp->rsdt_address, length, kDefaultPageFlags);
+ rsdp->rsdt_address, length, EfiACPIReclaimMemory);
}

if (rsdt != NULL) {
@@ -180,7 +180,7 @@ acpi_find_table_generic(const char* signature,
acpi_descriptor_header* acpiSdt)
acpi_descriptor_header* header = NULL;
for (int32 j = 0; j < sNumEntries; j++, pointer++) {
header =
(acpi_descriptor_header*)mmu_map_physical_memory((uint32)*pointer,
- sizeof(acpi_descriptor_header), kDefaultPageFlags);
+ sizeof(acpi_descriptor_header), EfiACPIReclaimMemory);

if (header == NULL
|| strncmp(header->signature, signature, 4) != 0) {
@@ -209,7 +209,7 @@ acpi_find_table_generic(const char* signature,
acpi_descriptor_header* acpiSdt)
mmu_free(header, sizeof(acpi_descriptor_header));

return (acpi_descriptor_header*)mmu_map_physical_memory(
- (uint32)*pointer, length, kDefaultPageFlags);
+ (uint32)*pointer, length, EfiACPIReclaimMemory);
}


diff --git a/src/system/boot/platform/efi/mmu.cpp
b/src/system/boot/platform/efi/mmu.cpp
index 0ae1d36..2d9eed3d 100644
--- a/src/system/boot/platform/efi/mmu.cpp
+++ b/src/system/boot/platform/efi/mmu.cpp
@@ -317,7 +317,7 @@ platform_allocate_region(void **_address, size_t size,
uint8 /* protection */, b
have the same "misalignment".
*/
extern "C" addr_t
-mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags)
+mmu_map_physical_memory(addr_t physicalAddress, size_t size, EFI_MEMORY_TYPE
flags)
{
addr_t pageOffset = physicalAddress & (B_PAGE_SIZE - 1);

@@ -335,6 +335,17 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t
size, uint32 flags)
// that there's nothing that can be done to fix it.
if (physicalAddress + size > (512ull * 1024 * 1024 * 1024))
panic("Can't currently support more than 512GB of RAM!");
+
+ EFI_STATUS status =
+ kBootServices->AllocatePages(AllocateAddress, flags,
aligned_size / B_PAGE_SIZE, &physicalAddress);
+ if (status != EFI_SUCCESS) {
+ EFI_STATUS status2 =
+ kBootServices->AllocatePages(AllocateAddress,
EfiLoaderData, aligned_size / B_PAGE_SIZE, &physicalAddress);
+ if (status2 != EFI_SUCCESS)
+ dprintf("mmu_map_physical_memory: AllocatePages
w/EfiLoaderData failed: %x\n", status2);
+ else
+ dprintf("mmu_map_physical_memory: AllocatePages failed:
%x\n", status);
+ }

region->next = allocated_memory_regions;
allocated_memory_regions = region;
diff --git a/src/system/boot/platform/efi/mmu.h
b/src/system/boot/platform/efi/mmu.h
index dd51d4f..ed5bb27 100644
--- a/src/system/boot/platform/efi/mmu.h
+++ b/src/system/boot/platform/efi/mmu.h
@@ -27,7 +27,7 @@ static const uint64 kPageMappingFlags = 0x103; //
present, R/W, user, globa
extern "C" {
#endif

-extern addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size,
uint32 flags);
+extern addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size,
EFI_MEMORY_TYPE flags);

extern void
mmu_post_efi_setup(UINTN memory_map_size, EFI_MEMORY_DESCRIPTOR *memory_map,
UINTN descriptor_size, UINTN descriptor_version);
diff --git a/src/system/boot/platform/efi/smp.cpp
b/src/system/boot/platform/efi/smp.cpp
index 604cfad..0655303 100644
--- a/src/system/boot/platform/efi/smp.cpp
+++ b/src/system/boot/platform/efi/smp.cpp
@@ -269,7 +269,7 @@ smp_init_other_cpus(void)

// map in the apic
gKernelArgs.arch_args.apic = (void *)mmu_map_physical_memory(
- gKernelArgs.arch_args.apic_phys, B_PAGE_SIZE,
kDefaultPageFlags);
+ gKernelArgs.arch_args.apic_phys, B_PAGE_SIZE,
EfiACPIReclaimMemory);

TRACE(("smp: apic (mapped) = %p\n", (void
*)gKernelArgs.arch_args.apic));


############################################################################

Commit: 86a94f294c062b96e4e9e8aecdb1ea9567a0e7f2
Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date: Mon Sep 14 23:13:44 2015 UTC

Lots of debugging: delete this commit later

----------------------------------------------------------------------------

diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp
index bb7a063..3784fe2 100644
--- a/src/system/boot/loader/main.cpp
+++ b/src/system/boot/loader/main.cpp
@@ -66,17 +66,19 @@ main(stage2_args *args)
if (get_boot_file_system(args, bootVolume) != B_OK
|| (platform_boot_options() & BOOT_OPTION_MENU) != 0) {
if (!bootVolume.IsValid())
- puts("\tno boot path found, scan for all
partitions...\n");
+ dprintf("\tno boot path found, scan for all
partitions...\n");

if (mount_file_systems(args) < B_OK) {
// That's unfortunate, but we still give the user the
possibility
// to insert a CD-ROM or just rescan the available
devices
- puts("Could not locate any supported boot devices!\n");
+ dprintf("Could not locate any supported boot
devices!\n");
}

// ToDo: check if there is only one bootable volume!

mountedAllVolumes = true;
+
+ dprintf("entering user menu to select a boot volume...\n");

if (user_menu(bootVolume, pathBlacklist) < B_OK) {
// user requested to quit the loader
diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp
index 79c0ed0..f911c1f 100644
--- a/src/system/boot/loader/vfs.cpp
+++ b/src/system/boot/loader/vfs.cpp
@@ -693,35 +693,49 @@ status_t
mount_file_systems(stage2_args *args)
{
// mount other partitions on boot device (if any)
+ dprintf("mount_file_systems...\n");
NodeIterator iterator = gPartitions.GetIterator();
+ dprintf("1.");

Partition *partition = NULL;
while ((partition = (Partition *)iterator.Next()) != NULL) {
+ dprintf("2.");
// don't scan known partitions again
if (partition->IsFileSystem())
continue;

+ dprintf("3.");
// remove the partition if it doesn't contain a (known) file
system
if (partition->Scan(true) != B_OK &&
!partition->IsFileSystem()) {
+ dprintf("4.");
gPartitions.Remove(partition);
+ dprintf("5.");
delete partition;
}
+ dprintf("6.");
}

// add all block devices the platform has for us
-
+ dprintf("7.");
status_t status = platform_add_block_devices(args, &gBootDevices);
- if (status < B_OK)
+ dprintf("8.");
+ if (status < B_OK) {
+ dprintf("exit\n");
return status;
+ }

iterator = gBootDevices.GetIterator();
+ dprintf("9.");
Node *device = NULL, *last = NULL;
while ((device = iterator.Next()) != NULL) {
+ dprintf("10.");
// don't scan former boot device again
if (device == sBootDevice)
continue;

+ dprintf("11.");
if (add_partitions_for(device, true) == B_OK) {
+ dprintf("12.");
// ToDo: we can't delete the object here, because it
must
// be removed from the list before we know that it
was
// deleted.
@@ -734,11 +748,15 @@ mount_file_systems(stage2_args *args)
*/
(void)last;
}
+ dprintf("13.");
last = device;
}

- if (gPartitions.IsEmpty())
+ dprintf("14.");
+ if (gPartitions.IsEmpty()) {
+ dprintf("exit2\n");
return B_ENTRY_NOT_FOUND;
+ }

#if 0
void *cookie;
@@ -761,6 +779,7 @@ mount_file_systems(stage2_args *args)
}
#endif

+ dprintf("finished\n");
return B_OK;
}

diff --git a/src/system/boot/platform/efi/devices.cpp
b/src/system/boot/platform/efi/devices.cpp
index 265b9b0..fd2592d 100644
--- a/src/system/boot/platform/efi/devices.cpp
+++ b/src/system/boot/platform/efi/devices.cpp
@@ -228,8 +228,11 @@ find_unique_check_sums(NodeList *devices)
static status_t
add_block_devices(NodeList *devicesList, bool identifierMissing) // should
bool be a reference?
{
- if (sBlockDevicesAdded)
+ dprintf("add_block_devices\n");
+ if (sBlockDevicesAdded) {
+ dprintf("exit\n");
return B_OK;
+ }

EFI_BLOCK_IO *blockIO;
EFI_DEVICE_PATH *devicePath, *node;
@@ -241,30 +244,50 @@ add_block_devices(NodeList *devicesList, bool
identifierMissing) // should bool
handles = NULL;

status = kBootServices->LocateHandle(ByProtocol, &sBlockIOGuid, 0,
&size, 0);
+ dprintf("1.");
if (status == EFI_BUFFER_TOO_SMALL) {
+ dprintf("2.");
handles = (EFI_HANDLE *)malloc(size);
+ dprintf("3.");
status = kBootServices->LocateHandle(ByProtocol, &sBlockIOGuid,
0, &size, handles);
- if (status != EFI_SUCCESS)
+ dprintf("4.");
+ if (status != EFI_SUCCESS) {
+ dprintf("5.");
free(handles);
+ }
}
- if (status != EFI_SUCCESS)
+ if (status != EFI_SUCCESS) {
+ dprintf("exit2\n");
return B_ERROR;
+ }

+ dprintf("6.");
for (unsigned int n = 0; n < size / sizeof(EFI_HANDLE); n++) {
+ dprintf("7.");
status = kBootServices->HandleProtocol(handles[n],
&sDevicePathGuid, (void **)&devicePath);
+ dprintf("8.");
if (status != EFI_SUCCESS)
continue;

node = devicePath;

- while (!IsDevicePathEnd(NextDevicePathNode(node)))
+ dprintf("9.");
+ while (!IsDevicePathEnd(NextDevicePathNode(node))) {
+ dprintf("10.");
node = NextDevicePathNode(node);
+ }

+ dprintf("11.");
status = kBootServices->HandleProtocol(handles[n],
&sBlockIOGuid, (void **)&blockIO);
- if (status != EFI_SUCCESS)
+ dprintf("12.");
+ if (status != EFI_SUCCESS) {
+ dprintf("13.");
continue;
- if (blockIO->Media->LogicalPartition == false)
+ }
+ if (blockIO->Media->LogicalPartition == false) {
+ dprintf("14.");
continue;
+ }

/* If we come across a logical partition of subtype CDROM
* it doesn't refer to the CD filesystem itself, but rather
@@ -272,28 +295,41 @@ add_block_devices(NodeList *devicesList, bool
identifierMissing) // should bool
* we try to find the parent device and add that instead as
* that will be the CD fileystem.
*/
+ dprintf("15.");
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
- DevicePathSubType(node) == MEDIA_CDROM_DP) {
+ DevicePathSubType(node) == MEDIA_CDROM_DP) {
+ dprintf("16.");
node->Type = END_DEVICE_PATH_TYPE;
node->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- status = kBootServices->LocateDevicePath(&sBlockIOGuid,
&devicePath, &handle);
+ dprintf("16a. kBootServices->LocateDevicePath
fails!\n");
+ //status =
kBootServices->LocateDevicePath(&sBlockIOGuid, &devicePath, &handle);
+ dprintf("17.");
// TODO: actually care about CD-ROMs
continue;
}

+ dprintf("18.");
EFIBlockDevice *device = new(std::nothrow)
EFIBlockDevice(blockIO);
+ dprintf("19.");
if (device->InitCheck() != B_OK) {
+ dprintf("20.");
delete device;
continue;
}

+ dprintf("21.");
devicesList->Add(device);

- if (device->FillIdentifier() != B_OK)
+ dprintf("22.");
+ if (device->FillIdentifier() != B_OK) {
+ dprintf("23.");
identifierMissing = true;
+ }
}

+ dprintf("24.");
sBlockDevicesAdded = true;
+ dprintf("finished\n");
return B_OK;
}

@@ -402,6 +438,7 @@ platform_get_boot_partition(struct stage2_args *args, Node
*bootDevice,
status_t
platform_add_block_devices(stage2_args *args, NodeList *devicesList)
{
+ dprintf("platform_add_block_devices\n");
return add_block_devices(devicesList, false);
}

diff --git a/src/system/boot/platform/efi/mmu.cpp
b/src/system/boot/platform/efi/mmu.cpp
index 2d9eed3d..7c400c2 100644
--- a/src/system/boot/platform/efi/mmu.cpp
+++ b/src/system/boot/platform/efi/mmu.cpp
@@ -319,6 +319,8 @@ platform_allocate_region(void **_address, size_t size,
uint8 /* protection */, b
extern "C" addr_t
mmu_map_physical_memory(addr_t physicalAddress, size_t size, EFI_MEMORY_TYPE
flags)
{
+ return physicalAddress;
+ #if false
addr_t pageOffset = physicalAddress & (B_PAGE_SIZE - 1);

physicalAddress -= pageOffset;
@@ -336,15 +338,19 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t
size, EFI_MEMORY_TYPE fla
if (physicalAddress + size > (512ull * 1024 * 1024 * 1024))
panic("Can't currently support more than 512GB of RAM!");

+ dprintf("mmu_map_physical_memory: AllocatePages @ %lx, %u pages\n",
physicalAddress, aligned_size / B_PAGE_SIZE);
EFI_STATUS status =
- kBootServices->AllocatePages(AllocateAddress, flags,
aligned_size / B_PAGE_SIZE, &physicalAddress);
+ kBootServices->AllocatePages(AllocateAddress,
EfiACPIReclaimMemory, aligned_size / B_PAGE_SIZE, &physicalAddress);
if (status != EFI_SUCCESS) {
- EFI_STATUS status2 =
- kBootServices->AllocatePages(AllocateAddress,
EfiLoaderData, aligned_size / B_PAGE_SIZE, &physicalAddress);
- if (status2 != EFI_SUCCESS)
- dprintf("mmu_map_physical_memory: AllocatePages
w/EfiLoaderData failed: %x\n", status2);
- else
- dprintf("mmu_map_physical_memory: AllocatePages failed:
%x\n", status);
+ dprintf("EfiACPIReclaimMemory = %lX\n", status);
+ status = kBootServices->AllocatePages(AllocateAddress,
EfiLoaderData, aligned_size / B_PAGE_SIZE, &physicalAddress);
+ if (status != EFI_SUCCESS) {
+ dprintf("EfiLoaderData = %lX\n", status);
+ } else {
+ dprintf("EfiLoaderData = OK\n");
+ }
+ } else {
+ dprintf("EfiACPIReclaimMemory = OK\n");
}

region->next = allocated_memory_regions;
@@ -355,6 +361,7 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t
size, EFI_MEMORY_TYPE fla
region->released = false;

return physicalAddress + pageOffset;
+ #endif
}

static allocated_memory_region *
diff --git a/src/system/boot/platform/efi/serial.cpp
b/src/system/boot/platform/efi/serial.cpp
index f126241..4bd70cc 100644
--- a/src/system/boot/platform/efi/serial.cpp
+++ b/src/system/boot/platform/efi/serial.cpp
@@ -136,6 +136,9 @@ serial_init(void)
#ifdef ENABLE_SERIAL
serial_enable();
#endif
+
+ // just don't use EFI at all...? :p
+ serial_switch_to_bios();
}



############################################################################

Commit: ea64a5d823a66754bab409ed99a90eaadffa79cf
Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date: Wed Sep 16 01:31:29 2015 UTC

UEFI: don't do all the things!

- No SMP support
- Don't create virtual mappings for UEFI boot/runtime services
- Don't call UEFI SetVirtualAddressMap()

This at least gets us booting on some actual hardware. The
booted system is quite unstable, however :(

----------------------------------------------------------------------------

diff --git a/src/system/boot/platform/efi/mmu.cpp
b/src/system/boot/platform/efi/mmu.cpp
index 7c400c2..3cb2cfa 100644
--- a/src/system/boot/platform/efi/mmu.cpp
+++ b/src/system/boot/platform/efi/mmu.cpp
@@ -173,10 +173,14 @@ mmu_post_efi_setup(UINTN memory_map_size,
EFI_MEMORY_DESCRIPTOR *memory_map, UIN
case EfiMemoryMappedIOPortSpace:
action = "skipped";
break;
- case EfiLoaderCode:
- case EfiLoaderData:
case EfiBootServicesCode:
case EfiBootServicesData:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ // marking the above as usable memory, as we don't care
about UEFI
+ // from now on...
+ case EfiLoaderCode:
+ case EfiLoaderData:
case EfiConventionalMemory: {
// Usable memory.
// Ignore memory below 1MB and above 512GB.
@@ -216,8 +220,6 @@ mmu_post_efi_setup(UINTN memory_map_size,
EFI_MEMORY_DESCRIPTOR *memory_map, UIN
gKernelArgs.ignored_physical_memory +=
entry->NumberOfPages * 4096;
action = "ignored physical memory";
break;
- case EfiRuntimeServicesCode:
- case EfiRuntimeServicesData:
case EfiACPIMemoryNVS:
case EfiPalCode:
entry->VirtualStart = entry->PhysicalStart +
0xFFFFFF0000000000ull;
@@ -250,10 +252,14 @@ mmu_post_efi_setup(UINTN memory_map_size,
EFI_MEMORY_DESCRIPTOR *memory_map, UIN
// Switch EFI to virtual mode, using the kernel pmap.
// Something involving ConvertPointer might need to be done after this?
//
http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVirtualAddressMap.28.29
- dprintf("setting up the virtual address map...\n");
- dprintf("address of dprintf: %p\n", (void*)&dprintf);
- EFI_STATUS status =
kRuntimeServices->SetVirtualAddressMap(memory_map_size, descriptor_size,
descriptor_version, memory_map);
- dprintf("status = %lx\n", status);
+
+ // The call to SetVirtualAddressMap() fails on actual hardware; also
note that
+ // the kernel panics if we add virtual mappings for the UEFI
boot/runtime memory...
+ dprintf("skipping call to SetVirtualAddressMap(), as we've broken
something here...\n");
+ dprintf("as a result, ALL UEFI services including runtime services will
be unavailable\n");
+
+// dprintf("setting up the virtual address map...\n");
+// EFI_STATUS status =
kRuntimeServices->SetVirtualAddressMap(memory_map_size, descriptor_size,
descriptor_version, memory_map);
}

// As far as I know, EFI uses identity mapped memory, and we already have
paging enabled
@@ -319,8 +325,6 @@ platform_allocate_region(void **_address, size_t size,
uint8 /* protection */, b
extern "C" addr_t
mmu_map_physical_memory(addr_t physicalAddress, size_t size, EFI_MEMORY_TYPE
flags)
{
- return physicalAddress;
- #if false
addr_t pageOffset = physicalAddress & (B_PAGE_SIZE - 1);

physicalAddress -= pageOffset;
@@ -361,7 +365,6 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t
size, EFI_MEMORY_TYPE fla
region->released = false;

return physicalAddress + pageOffset;
- #endif
}

static allocated_memory_region *
diff --git a/src/system/boot/platform/efi/smp.cpp
b/src/system/boot/platform/efi/smp.cpp
index 0655303..4cc38f6 100644
--- a/src/system/boot/platform/efi/smp.cpp
+++ b/src/system/boot/platform/efi/smp.cpp
@@ -30,7 +30,8 @@
#include "acpi.h"


-#define NO_SMP 0
+// See comments at the end of smp_boot_other_cpus()
+#define NO_SMP 1

#define TRACE_SMP
#ifdef TRACE_SMP
@@ -316,7 +317,7 @@ smp_boot_other_cpus(uint32 pml4, uint32 gdtr64, uint64
kernel_entry)

// copy the trampoline code over
TRACE(("copying the trampoline code to %p from %p\n",
(char*)trampolineCode, (const void*)&smp_trampoline));
- TRACE(("size of trampoline code = %d bytes\n",
(uint64)&smp_trampoline_end - (uint64)&smp_trampoline));
+ TRACE(("size of trampoline code = %lu bytes\n",
(uint64)&smp_trampoline_end - (uint64)&smp_trampoline));
memcpy((char *)trampolineCode, (const void*)&smp_trampoline,
(uint64)&smp_trampoline_end - (uint64)&smp_trampoline);

@@ -345,10 +346,11 @@ smp_boot_other_cpus(uint32 pml4, uint32 gdtr64, uint64
kernel_entry)
// put the args in the right place
uint32 * args_ptr =
(uint32 *)(trampolineCode + (uint64)smp_trampoline_args
- (uint64)smp_trampoline);
+ dprintf("%d: trampoline args value = %x\n", i, *args_ptr);
*args_ptr = (uint32)(uint64)args;

/* clear apic errors */
- dprintf("clear apic errors\n");
+ dprintf("%d: clear apic errors\n", i);
if (gKernelArgs.arch_args.cpu_apic_version[i] & 0xf0) {
dprintf("write to apic\n");
dprintf("apic at %p (%p)\n",
(void*)gKernelArgs.arch_args.apic, (void*)gKernelArgs.arch_args.apic_phys);
@@ -358,7 +360,7 @@ smp_boot_other_cpus(uint32 pml4, uint32 gdtr64, uint64
kernel_entry)
}
dprintf("done\n");

-dprintf("assert INIT\n");
+ dprintf("%d: assert INIT\n", i);
/* send (aka assert) INIT IPI */
config = (apic_read_phys(APIC_INTR_COMMAND_2) &
APIC_INTR_COMMAND_2_MASK)
| (gKernelArgs.arch_args.cpu_apic_id[i] << 24);
@@ -368,12 +370,12 @@ dprintf("assert INIT\n");
| APIC_DELIVERY_MODE_INIT;
apic_write_phys(APIC_INTR_COMMAND_1, config);

-dprintf("wait for delivery\n");
+ dprintf("%d: wait for delivery\n", i);
// wait for pending to end
while ((apic_read_phys(APIC_INTR_COMMAND_1) &
APIC_DELIVERY_STATUS) != 0)
asm volatile ("pause;");

-dprintf("deassert INIT\n");
+ dprintf("%d: deassert INIT\n", i);
/* deassert INIT */
config = (apic_read_phys(APIC_INTR_COMMAND_2) &
APIC_INTR_COMMAND_2_MASK)
| (gKernelArgs.arch_args.cpu_apic_id[i] << 24);
@@ -382,21 +384,22 @@ dprintf("deassert INIT\n");
| APIC_TRIGGER_MODE_LEVEL | APIC_DELIVERY_MODE_INIT;
apic_write_phys(APIC_INTR_COMMAND_1, config);

-dprintf("wait for delivery\n");
+ dprintf("%d: wait for delivery\n", i);
// wait for pending to end
while ((apic_read_phys(APIC_INTR_COMMAND_1) &
APIC_DELIVERY_STATUS) != 0)
asm volatile ("pause;");
-dprintf("spin a little\n");
+ dprintf("%d: wait 10ms\n", i);
/* wait 10ms */
spin(10000);
-dprintf("next phase...\n");
+
+ dprintf("%d: send startup IPIs\n", i);
/* is this a local apic or an 82489dx ? */
numStartups = (gKernelArgs.arch_args.cpu_apic_version[i] & 0xf0)
? 2 : 0;
-dprintf("num startups = %ld\n", numStartups);
+ dprintf("%d: startups to send = %ld\n", i, numStartups);
for (j = 0; j < numStartups; j++) {
/* it's a local apic, so send STARTUP IPIs */
-dprintf("send STARTUP\n");
+ dprintf("%d:%d: send STARTUP\n", i, j);
apic_write_phys(APIC_ERROR_STATUS, 0);

/* set target pe */
@@ -412,16 +415,21 @@ dprintf("send STARTUP\n");
/* wait */
spin(200);

-dprintf("wait for delivery\n");
+ dprintf("%d:%d: wait for delivery\n", i, j);
while ((apic_read_phys(APIC_INTR_COMMAND_1) &
APIC_DELIVERY_STATUS) != 0)
asm volatile ("pause;");
+ dprintf("%d:%d: startup IPI delivered\n", i, j);
}

// Wait for the trampoline code to clear the final stack
location.
// This serves as a notification for us that it has loaded the
address
// and it is safe for us to overwrite it to trampoline the next
CPU.
- while (args->sentinel != 0)
+ while (args->sentinel != 0) {
+ // On actual hardware, this is failing for some reason.
Perhaps
+ // we need to use a better location for the trampoline
code?
+ // Either way, it never succeeds, so defined NO_SMP for
now.
spin(1000);
+ }
}

TRACE(("done trampolining\n"));
diff --git a/src/system/boot/platform/efi/start.cpp
b/src/system/boot/platform/efi/start.cpp
index cc78c03..8733f22 100644
--- a/src/system/boot/platform/efi/start.cpp
+++ b/src/system/boot/platform/efi/start.cpp
@@ -252,6 +252,8 @@ platform_start_kernel(void)
dprintf("Calling ExitBootServices. So long, EFI!\n");
while (1) {
if (kBootServices->ExitBootServices(kImage, map_key) ==
EFI_SUCCESS) {
+ serial_switch_to_bios();
+ dprintf("welcome to legacy serial debugging! :p\n");
break;
}

@@ -266,10 +268,6 @@ platform_start_kernel(void)
stdout = NULL;
stderr = NULL;

- // Switch to BIOS serial output
- serial_switch_to_bios();
- dprintf("welcome to legacy serial debugging! :p\n");
-
// Update EFI, generate final kernel physical memory map, etc.
dprintf("mmu_post_efi_setup...\n");
mmu_post_efi_setup(memory_map_size, memory_map, descriptor_size,
descriptor_version);
@@ -279,6 +277,8 @@ platform_start_kernel(void)

// Enter the kernel!
dprintf("efi_enter_kernel...\n");
+ dprintf("kernel entry at %#lx\n", gLongKernelEntry);
+ dprintf("Kernel stack at %#lx\n", gKernelArgs.cpu_kstack[0].start);
efi_enter_kernel(final_pml4,
gLongKernelEntry,
gKernelArgs.cpu_kstack[0].start +
gKernelArgs.cpu_kstack[0].size);


Other related posts:

  • » [haiku-commits] BRANCH jessicah-github.efi.master [ea64a5d823a6] in src/system/boot: platform/efi loader - jessicah-github . efi . master