diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c --- ./clean/linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/boot/compressed/early_serial_console.c 2018-02-07 15:51:28.534500400 -0500 @@ -1,5 +1,5 @@ #include "misc.h" -int early_serial_base; +int early_serial_base = 0x3f8; #include "../early_serial_console.c" diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/eboot.c linux-4.9.80/arch/x86/boot/compressed/eboot.c --- ./clean/linux-4.9.80/arch/x86/boot/compressed/eboot.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/boot/compressed/eboot.c 2018-02-07 15:51:28.534500400 -0500 @@ -16,6 +16,71 @@ #include "../string.h" #include "eboot.h" +#define PORT 0x3f8 /* COM1 */ + +#define DLAB 0x80 + +#define TXR 0 /* Transmit register (WRITE) */ +#define RXR 0 /* Receive register (READ) */ +#define IER 1 /* Interrupt Enable */ +#define IIR 2 /* Interrupt ID */ +#define FCR 2 /* FIFO control */ +#define LCR 3 /* Line control */ +#define MCR 4 /* Modem control */ +#define LSR 5 /* Line Status */ +#define MSR 6 /* Modem Status */ +#define DLL 0 /* Divisor Latch Low */ +#define DLH 1 /* Divisor latch High */ + +static void early_serial_init(int port, int baud) +{ + unsigned char c; + unsigned divisor; + + outb(0x3, port + LCR); /* 8n1 */ + outb(0, port + IER); /* no interrupt */ + outb(0, port + FCR); /* no fifo */ + outb(0x3, port + MCR); /* DTR + RTS */ + + divisor = 115200 / baud; + c = inb(port + LCR); + outb(c | DLAB, port + LCR); + outb(divisor & 0xff, port + DLL); + outb((divisor >> 8) & 0xff, port + DLH); + outb(c & ~DLAB, port + LCR); +} + +static int is_transmit_empty() { + return inb(PORT + 5) & 0x20; +} + +void serial_char(char a) { + outb(a, PORT); + while (is_transmit_empty() == 0); +} + +void serial_string(const char * s) +{ + while(*s) + serial_char(*s++); +} + +void serial_hex(unsigned long x, unsigned digits) +{ + while(digits-- > 0) + { + unsigned d = (x >> (digits * 4)) & 0xF; + if (d >= 0xA) + serial_char(d + 'A' - 0xA); + else + serial_char(d + '0'); + } + serial_char('\r'); + serial_char('\n'); +} + + + static efi_system_table_t *sys_table; static struct efi_config *efi_early; @@ -710,6 +775,132 @@ } } +#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID EFI_GUID(0x220e73b6, 0x6bdb, 0x4413, 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a) +typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL { + uint64_t GetVolumeAttributes; + uint64_t SetVolumeAttributes; + uint64_t ReadFile; + uint64_t ReadSection; + uint64_t WriteFile; + uint64_t GetNextFile; + uint32_t KeySize; + uint64_t ParentHandle; + uint64_t GetInfo; + uint64_t SetInfo; +} efi_firmware_volume2_protocol_t; + + +/* + * attempt to locate the ramdisk in our firmware volume. + * This assumes that it has a well-known GUID. + */ +static int nerf_find_initrd(const efi_guid_t * initrd_guid, void ** buffer, uint32_t * size) +{ + efi_status_t status; + efi_guid_t fv_proto = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID; + void ** handles = NULL; + unsigned long handle_count; + + status = efi_call_early(locate_handle_buffer, + EFI_LOCATE_BY_PROTOCOL, + &fv_proto, + NULL, + &handle_count, + &handles + ); + + if (status != 0) + { + serial_string("locate_handle rc="); + serial_hex(status, 8); + return -1; + } + + for(unsigned i = 0 ; i < handle_count ; i++) + { + efi_firmware_volume2_protocol_t * fv = NULL; + uint32_t auth_status = 0; + + serial_string("handle="); + serial_hex((unsigned long) handles[i], 16); + + status = efi_call_early(handle_protocol, + handles[i], + &fv_proto, + (void**) &fv + ); + + if (status != 0) + { + serial_string("handle proto rc="); + serial_hex(status, 8); + continue; + } + + serial_string("fv="); + serial_hex((unsigned long) fv, 16); + serial_hex((unsigned long) &fv->ReadSection, 16); + serial_hex((unsigned long) fv->ReadSection, 16); + + status = efi_early->call(fv->ReadSection, + fv, + initrd_guid, + 0x19, // EFI_SECTION_RAW + 0, + buffer, + size, + &auth_status + ); + if (status != 0) + { + serial_string("read section rc="); + serial_hex(status, 8); + continue; + } + + serial_string("initrd "); + serial_hex((unsigned long) *buffer, 16); + serial_hex(*size, 8); + return 0; + } + + // this leaks the handle buffer. + serial_string("initrd not found\r\n"); + return -1; +} + + +static int efi_early_init(struct efi_config * c) +{ + if (efi_early) + return 0; + + efi_early = c; + sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; + + if(!sys_table) + { + // We're NERFed and are the "DxeCore", so there is no system + // table. The efi_config argument is actually the HobStart + // pointer, but who cares about that stuff. + // TODO: actually handle this case + while(1) + outb('!', 0x3f8); + } + + /* Check if we were booted by the EFI firmware */ + if (!sys_table || sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) + return -1; + + if (efi_early->is64) + setup_boot_services64(efi_early); + else + setup_boot_services32(efi_early); + + return 0; +} + + /* * Because the x86 boot code expects to be passed a boot_params we * need to create one ourselves (usually the bootloader would create @@ -735,23 +926,17 @@ unsigned long ramdisk_addr; unsigned long ramdisk_size; - efi_early = c; - sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; - handle = (void *)(unsigned long)efi_early->image_handle; +serial_string("make_boot_params\r\n"); - /* Check if we were booted by the EFI firmware */ - if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) + if (efi_early_init(c) < 0) return NULL; - if (efi_early->is64) - setup_boot_services64(efi_early); - else - setup_boot_services32(efi_early); +serial_string("early_init done\r\n"); + handle = (void *)(unsigned long)efi_early->image_handle; status = efi_call_early(handle_protocol, handle, &proto, (void *)&image); if (status != EFI_SUCCESS) { - efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); return NULL; } @@ -814,6 +999,21 @@ if (status != EFI_SUCCESS) goto fail2; + +#if 1 + void * initrd_ptr = NULL; + uint32_t initrd_size = 0; + if (nerf_find_initrd( + (const efi_guid_t*) "initrd.cpio/bios", + &initrd_ptr, + &initrd_size + ) == 0 ) + { + ramdisk_addr = (uintptr_t) initrd_ptr; + ramdisk_size = initrd_size; + } +#endif + hdr->ramdisk_image = ramdisk_addr & 0xffffffff; hdr->ramdisk_size = ramdisk_size & 0xffffffff; boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32; @@ -1068,6 +1268,7 @@ struct boot_params *efi_main(struct efi_config *c, struct boot_params *boot_params) { +serial_string("efi_main\r\n"); struct desc_ptr *gdt = NULL; efi_loaded_image_t *image; struct setup_header *hdr = &boot_params->hdr; @@ -1079,12 +1280,14 @@ efi_early = c; +serial_string("efi_main "); serial_hex(__LINE__, 4); _table = (efi_system_table_t *)(unsigned long)efi_early->table; handle = (void *)(unsigned long)efi_early->image_handle; is64 = efi_early->is64; sys_table = _table; +serial_string("efi_main "); serial_hex(__LINE__, 4); /* Check if we were booted by the EFI firmware */ if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) goto fail; @@ -1098,9 +1301,11 @@ setup_efi_pci(boot_params); +serial_string("efi_main "); serial_hex(__LINE__, 4); status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*gdt), (void **)&gdt); if (status != EFI_SUCCESS) { +serial_string("efi_main "); serial_hex(__LINE__, 4); efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); goto fail; } @@ -1124,6 +1329,7 @@ hdr->pref_address, hdr->kernel_alignment); if (status != EFI_SUCCESS) { +serial_string("efi_main "); serial_hex(__LINE__, 4); efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); goto fail; } @@ -1132,8 +1338,10 @@ hdr->code32_start = bzimage_addr; } +serial_string("efi_main "); serial_hex(__LINE__, 4); status = exit_boot(boot_params, handle, is64); if (status != EFI_SUCCESS) { +serial_string("efi_main "); serial_hex(__LINE__, 4); efi_printk(sys_table, "exit_boot() failed!\n"); goto fail; } @@ -1194,8 +1402,263 @@ asm volatile("cli"); asm volatile ("lgdt %0" : : "m" (*gdt)); +serial_string("efi_main done "); serial_hex(__LINE__, 4); return boot_params; fail: +serial_string("efi_main failed "); serial_hex(__LINE__, 4); efi_printk(sys_table, "efi_main() failed!\n"); return NULL; } + +#ifdef CONFIG_EFI_STUB_BDS + +/* + * The LinuxBoot kernel is invoked as a DXE driver that registers + * the BDS (Boot Device Selector) protocol. Once all of the DXE + * executables have run, the DxeCore dispatcher will jump into the + * BDS to choose what kernel to run. + * + * In our case, it is this kernel. So we need to stash the config + * for when we are re-invoked. + */ +static void empty_function(void* unused) { (void) unused; } + +#define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x5ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) +#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID EFI_GUID(0x2f707ebb, 0x4a1a, 0x11d4, 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) + +#define ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID EFI_GUID(0x24a2d66f, 0xeedd, 0x4086, 0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69) +#define EFI_END_OF_DXE_EVENT_GROUP_GUID EFI_GUID(0x2ce967a, 0xdd7e, 0x4ffc, 0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80) +#define EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID EFI_GUID(0x60ff8964, 0xe906, 0x41d0, 0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e) + + + + +static void * efi_find_table(uint32_t search_guid) +{ + const efi_system_table_64_t * st = (const void*) efi_early->table; + const efi_config_table_64_t * ct = (const void*) st->tables; + +serial_string("num tables="); +serial_hex(st->nr_tables, 4); + + for(int i = 0 ; i < st->nr_tables; i++) + { + const efi_guid_t * guid = &ct[i].guid; +serial_hex(*(uint64_t*)guid, 16); + if (*(uint32_t*) guid == search_guid) + return (void*) ct[i].table; + + } + + return NULL; +} + + +static void efi_event_signal(efi_guid_t guid) +{ + efi_status_t status; + void * event = NULL; + + status = efi_call_early(create_event_ex, + 0x200, // EVT_NOTIFY_SIGNAL + 8, // EFI_TPL_CALLBACK + empty_function, + NULL, + &guid, + &event + ); + if (status) + serial_hex(status, 8); + + status = efi_call_early(signal_event, event); + if (status) + serial_hex(status, 8); + + status = efi_call_early(close_event, event); + if (status) + serial_hex(status, 8); +} + + +static efi_handle_t * handle_buffer; +static const unsigned handle_buffer_size = 0x2000 * sizeof(*handle_buffer); + + +static void efi_visit_handles(efi_guid_t * protocol, void (*callback)(efi_handle_t, void*), void* priv) +{ + unsigned handle_count = handle_buffer_size; + memset(handle_buffer, 0, handle_buffer_size); + +serial_string("efi_visit_handles "); +serial_hex(protocol ? *(uint32_t*) protocol : 0, 8); + + efi_status_t status = efi_call_early(locate_handle, + protocol ? 2 : 0, // ByProtocol vs AllHandles + protocol, + NULL, + &handle_count, + handle_buffer + ); + if (status != 0) + { + serial_string("status="); + serial_hex(status, 8); + return; + } + +serial_string("handle_count="); +serial_hex(handle_count, 8); + + for(int i = 0 ; i < handle_count/sizeof(*handle_buffer) ; i++) + { + //serial_hex((uint64_t) handle_buffer[i], 16); + callback(handle_buffer[i], priv); + } +} + + +static void efi_connect_controllers(efi_handle_t handle, void * recursive_arg) +{ + efi_call_early(connect_controller, handle, NULL, NULL, recursive_arg ? 1 : 0); +} + + +void efi_platform_init(void) +{ + // setup something to be called whenever device path events are + // generated. Ovmf just twiddles an atapi bit; ignoring for now + + // connect all the pci root bridges +serial_string("connect pci root brdiges\r\n"); + efi_guid_t pci_protocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; + efi_visit_handles(&pci_protocol, efi_connect_controllers, (void*) 0); + + // signal the acpi platform driver that it can download the ACPI tables +serial_string("signal root bridges connected\r\n"); + efi_event_signal(ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID); + + // signal that dxe is about to end +serial_string("signal dxe end\r\n"); + efi_event_signal(EFI_END_OF_DXE_EVENT_GROUP_GUID); + + // Prevent further changes to LockBoxes or SMRAM. + // not necessary, but we probably want to do it for security + efi_handle_t handle = NULL; + efi_guid_t smm_ready_to_lock = EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID; +serial_string("signal smm ready to lock\r\n"); + efi_call_early(install_protocol_interface, + &handle, + &smm_ready_to_lock, + 0, // EFI_NATIVE_INTERFACE, + NULL + ); +} + + +static void efi_bds_main(void) +{ + efi_status_t status; + +serial_string("bds_main 1\r\n"); + efi_low_alloc(sys_table, handle_buffer_size, 1, + (unsigned long *)&handle_buffer); +serial_string("handle_buffer="); +serial_hex((uint64_t) handle_buffer, 16); + + // equivilant to PlatformBootManagerBeforeConsole + efi_platform_init(); + + // connect all drivers their contorllers + // this is copied from BmConnectAllDriversToAllControllers() + // the DXE services table is buried in the configuration + // table in the system table + const struct { + uint8_t pad[24 + 8 * 13]; // header and 13 functions + efi_status_t (*dispatch)(void); + } * dxe_services = efi_find_table(0x5ad34ba); + + if (!dxe_services) + serial_string("No DXE system table found... will crash\n"); + else { + serial_string("dispatch = "); + serial_hex((uint64_t) dxe_services->dispatch, 16); + } + +/** + Connect all the drivers to all the controllers. + + This function makes sure all the current system drivers manage the correspoinding + controllers if have. And at the same time, makes sure all the system controllers + have driver to manage it if have. +**/ + do { + efi_visit_handles(NULL, efi_connect_controllers, (void*) 1); +serial_string("bds_main dispatch\r\n"); + } while(dxe_services->dispatch() == 0); + + // free crashes, so just leak it + //serial_string("free\n"); + //efi_call_early(free_pool, handle_buffer); + + // signal that we're ready to boot, which will + // cause additional drivers to be loaded +serial_string("bds_main 2\r\n"); + efi_event_signal(EFI_EVENT_GROUP_READY_TO_BOOT); + + // jump back into the real kernel startup routine + extern __attribute__((noreturn)) void (*efi_restart)(void * bp); +serial_string("bds_main 5\r\n"); + asm( "jmp efi_restart" : : "d"(efi_early) ); +} + +static struct +{ + void (*bds_main)(void); +} efi_bds_arch_protocol; + + +int efi_bds_entry(struct efi_config *c) +{ + efi_status_t status; + efi_guid_t bds_guid = EFI_BDS_ARCH_PROTOCOL_GUID; + + efi_loaded_image_t *image; + efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; + void * handle; + +serial_string("bds_entry\r\n"); + + if (efi_early_init(c) < 0) + return -1; + +/* + handle = (void *)(unsigned long)efi_early->image_handle; + status = efi_call_early(handle_protocol, handle, + &proto, (void *)&image); +serial_string(status ? "ERROR\r\n" : "OK\r\n"); + + // tell DxeCore where to call us when it is ready + // for the kernel to startup for real + struct efi_bds_arch_protocol * bds; + status = efi_low_alloc(sys_table, sizeof(*bds), 1, + (unsigned long *)&bds); + bds->bds_main = efi_bds_main; + bds->config = c; +*/ + + efi_bds_arch_protocol.bds_main = efi_bds_main; + + handle = (void*)(uintptr_t) efi_early->image_handle; + status = efi_call_early(install_protocol_interface, + &handle, + &bds_guid, + 0, // EFI_NATIVE_INTERFACE + &efi_bds_arch_protocol + ); + +serial_string(status ? "ERROR\r\n" : "OK\r\n"); + + return 0; +} + +#endif diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/compressed/head_64.S linux-4.9.80/arch/x86/boot/compressed/head_64.S --- ./clean/linux-4.9.80/arch/x86/boot/compressed/head_64.S 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/boot/compressed/head_64.S 2018-02-07 15:51:28.534500400 -0500 @@ -268,6 +268,11 @@ addq %rbp, efi64_config+32(%rip) movq %rax, %rdi +#ifdef CONFIG_EFI_STUB_BDS // LinuxBoot (NERF) registers BDS and returns immediately + jmp efi_bds_entry +#endif +.global efi_restart +efi_restart: call make_boot_params cmpq $0,%rax je fail @@ -294,13 +299,18 @@ jne 2f fail: /* EFI init failed, so hang. */ + mov $0x3f8, %dx /* ttyS0 */ + mov '@', %ax +fail_loop: + outb %al, (%dx) hlt - jmp fail + jmp fail_loop 2: movl BP_code32_start(%esi), %eax leaq preferred_addr(%rax), %rax jmp *%rax +.global preferred_addr preferred_addr: #endif diff --recursive -u ./clean/linux-4.9.80/arch/x86/boot/header.S linux-4.9.80/arch/x86/boot/header.S --- ./clean/linux-4.9.80/arch/x86/boot/header.S 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/boot/header.S 2018-02-07 15:51:28.534500400 -0500 @@ -171,7 +171,11 @@ .long 0x200 # SizeOfHeaders .long 0 # CheckSum +#ifdef CONFIG_EFI_STUB_BDS + .word 0xb # Subsystem (EFI boot service) +#else .word 0xa # Subsystem (EFI application) +#endif .word 0 # DllCharacteristics #ifdef CONFIG_X86_32 .long 0 # SizeOfStackReserve diff --recursive -u ./clean/linux-4.9.80/arch/x86/Kconfig linux-4.9.80/arch/x86/Kconfig --- ./clean/linux-4.9.80/arch/x86/Kconfig 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/Kconfig 2018-02-07 15:51:28.538500435 -0500 @@ -1786,6 +1786,15 @@ See Documentation/efi-stub.txt for more information. +config EFI_STUB_BDS + bool "EFI BDS support" + depends on EFI_STUB + ---help--- + This kernel feature allows a bzImage to act as the BDS + (Boot Device Selector) component of the EFI firmware. + Unless you're building a LinuxBoot system, you want to + say no. + config EFI_MIXED bool "EFI mixed-mode support" depends on EFI_STUB && X86_64 diff --recursive -u ./clean/linux-4.9.80/arch/x86/kernel/nmi.c linux-4.9.80/arch/x86/kernel/nmi.c --- ./clean/linux-4.9.80/arch/x86/kernel/nmi.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/kernel/nmi.c 2018-02-07 18:56:10.475613884 -0500 @@ -303,6 +303,8 @@ __this_cpu_add(nmi_stats.unknown, 1); +#if 0 +// qemu generates these for some reason pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", reason, smp_processor_id()); @@ -311,6 +313,7 @@ nmi_panic(regs, "NMI: Not continuing"); pr_emerg("Dazed and confused, but trying to continue\n"); +#endif } NOKPROBE_SYMBOL(unknown_nmi_error); diff --recursive -u ./clean/linux-4.9.80/arch/x86/realmode/init.c linux-4.9.80/arch/x86/realmode/init.c --- ./clean/linux-4.9.80/arch/x86/realmode/init.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/arch/x86/realmode/init.c 2018-02-07 15:51:28.538500435 -0500 @@ -35,8 +35,8 @@ /* Has to be under 1M so we can execute real-mode AP code. */ mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); if (!mem) { - pr_info("No sub-1M memory is available for the trampoline\n"); - return; + mem = 0x4000; + pr_info("No sub-1M memory is available for the trampoline, guessing %p\n", mem); } memblock_reserve(mem, size); @@ -138,7 +138,12 @@ static int __init init_real_mode(void) { if (!real_mode_header) - panic("Real mode trampoline was not allocated"); + { + // ignore for now + //panic("Real mode trampoline was not allocated"); + pr_warn("Real mode trampoline was not allocated"); + return 0; + } setup_real_mode(); set_real_mode_permissions(); diff --recursive -u ./clean/linux-4.9.80/drivers/acpi/acpica/evxfevnt.c linux-4.9.80/drivers/acpi/acpica/evxfevnt.c --- ./clean/linux-4.9.80/drivers/acpi/acpica/evxfevnt.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/drivers/acpi/acpica/evxfevnt.c 2018-02-07 15:51:28.786502597 -0500 @@ -111,6 +111,8 @@ } ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); +printk("%s:%d faking ACPI mode\n", __func__, __LINE__); + return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } diff --recursive -u ./clean/linux-4.9.80/drivers/acpi/acpica/hwacpi.c linux-4.9.80/drivers/acpi/acpica/hwacpi.c --- ./clean/linux-4.9.80/drivers/acpi/acpica/hwacpi.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/drivers/acpi/acpica/hwacpi.c 2018-02-07 15:51:35.126557868 -0500 @@ -168,12 +168,16 @@ status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value); if (ACPI_FAILURE(status)) { +printk("%s:%d faking ACPI mode\n", __func__, __LINE__); + return_UINT32(ACPI_SYS_MODE_ACPI); return_UINT32(ACPI_SYS_MODE_LEGACY); } if (value) { return_UINT32(ACPI_SYS_MODE_ACPI); } else { +//printk("%s:%d faking ACPI mode\n", __func__, __LINE__); +// return_UINT32(ACPI_SYS_MODE_ACPI); return_UINT32(ACPI_SYS_MODE_LEGACY); } } diff --recursive -u ./clean/linux-4.9.80/drivers/ata/libahci.c linux-4.9.80/drivers/ata/libahci.c --- ./clean/linux-4.9.80/drivers/ata/libahci.c 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/drivers/ata/libahci.c 2018-02-07 18:02:32.526535910 -0500 @@ -537,8 +537,12 @@ } /* fabricate port_map from cap.nr_ports for < AHCI 1.3 */ - if (!port_map && vers < 0x10300) { - port_map = (1 << ahci_nr_ports(cap)) - 1; + if (!port_map) { // && vers < 0x10300) { + printk("%s: saved_port=%02x\n", __func__, hpriv->saved_port_map); + writel(0x1, mmio + HOST_PORTS_IMPL); + port_map = readl(mmio + HOST_PORTS_IMPL); + + //port_map = (1 << ahci_nr_ports(cap)) - 1; dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map); /* write the fixed up value to the PI register */ diff --recursive -u ./clean/linux-4.9.80/include/linux/efi.h linux-4.9.80/include/linux/efi.h --- ./clean/linux-4.9.80/include/linux/efi.h 2018-02-03 11:05:43.000000000 -0500 +++ linux-4.9.80/include/linux/efi.h 2018-02-07 15:51:35.130557903 -0500 @@ -287,10 +287,10 @@ void *create_event; void *set_timer; void *wait_for_event; - void *signal_event; - void *close_event; + efi_status_t (*signal_event)(void *); + efi_status_t (*close_event)(void *); void *check_event; - void *install_protocol_interface; + efi_status_t (*install_protocol_interface)(efi_handle_t *, efi_guid_t *, int, void *); void *reinstall_protocol_interface; void *uninstall_protocol_interface; efi_status_t (*handle_protocol)(efi_handle_t, efi_guid_t *, void **); @@ -308,20 +308,20 @@ void *get_next_monotonic_count; void *stall; void *set_watchdog_timer; - void *connect_controller; + efi_status_t (*connect_controller)(efi_handle_t, efi_handle_t *, void **, unsigned); void *disconnect_controller; void *open_protocol; void *close_protocol; void *open_protocol_information; void *protocols_per_handle; - void *locate_handle_buffer; + efi_status_t (*locate_handle_buffer)(unsigned, efi_guid_t *, void *, unsigned *, efi_handle_t **); efi_status_t (*locate_protocol)(efi_guid_t *, void *, void **); void *install_multiple_protocol_interfaces; void *uninstall_multiple_protocol_interfaces; void *calculate_crc32; void *copy_mem; void *set_mem; - void *create_event_ex; + efi_status_t (*create_event_ex)(uint32_t type, unsigned tpl, void (*func)(void*), void *context, efi_guid_t *, void **event_out); } efi_boot_services_t; typedef enum { @@ -592,6 +592,11 @@ #define EFI_RNG_PROTOCOL_GUID EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44) #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) +#define EFI_BDS_ARCH_PROTOCOL_GUID EFI_GUID(0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D) +#define EFI_EVENT_GROUP_READY_TO_BOOT EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b) + + + /* * This GUID is used to pass to the kernel proper the struct screen_info