efi: Refactor CPU code to be arch-specific

* Migrate some platform agnostic architecture code into
  boot/arch from efi/arch. This helps to avoid conflicts
  between kernel and boot sources as well.
* Conflicts between arch_cpu in efi and kernel code means
  bootcode really should *never* directly use kernel arch
  headers. (other platforms don't, which is why they don't
  have this same issue)
* We carefully thread any needed kernel headers (namely
  assembly helper macros) into the bootloader headers without
  mixing in the whole conflicting kernel/arch headers.
* ARM now properly get its cpu init code called, and we
  progress further into the EFI bootloader.

Change-Id: If67ec9758b5ce68563ebd9eb45d5196401911c67
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2975
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Alexander von Gluck IV
2020-07-04 21:04:20 +00:00
committed by waddlesplash
parent 1f2666fd48
commit 89fd39f42a
12 changed files with 192 additions and 173 deletions
+1 -109
View File
@@ -18,6 +18,7 @@
#include <arch_thread_types.h>
#include <arch/x86/arch_altcodepatch.h>
#include <arch/x86/arch_cpuasm.h>
#include <arch/x86/descriptors.h>
#ifdef __x86_64__
@@ -497,115 +498,6 @@ struct intel_microcode_extended_signature {
};
#define nop() __asm__ ("nop"::)
#define x86_read_cr0() ({ \
size_t _v; \
__asm__("mov %%cr0,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr0(value) \
__asm__("mov %0,%%cr0" : : "r" (value))
#define x86_read_cr2() ({ \
size_t _v; \
__asm__("mov %%cr2,%0" : "=r" (_v)); \
_v; \
})
#define x86_read_cr3() ({ \
size_t _v; \
__asm__("mov %%cr3,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr3(value) \
__asm__("mov %0,%%cr3" : : "r" (value))
#define x86_read_cr4() ({ \
size_t _v; \
__asm__("mov %%cr4,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr4(value) \
__asm__("mov %0,%%cr4" : : "r" (value))
#define x86_read_dr3() ({ \
size_t _v; \
__asm__("mov %%dr3,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_dr3(value) \
__asm__("mov %0,%%dr3" : : "r" (value))
#define invalidate_TLB(va) \
__asm__("invlpg (%0)" : : "r" (va))
#define wbinvd() \
__asm__ volatile ("wbinvd" : : : "memory")
#define set_ac() \
__asm__ volatile (ASM_STAC : : : "memory")
#define clear_ac() \
__asm__ volatile (ASM_CLAC : : : "memory")
#define xgetbv(reg) ({ \
uint32 low, high; \
__asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
(low | (uint64)high << 32); \
})
#define xsetbv(reg, value) { \
uint32 low = value; uint32 high = value >> 32; \
__asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
#define out8(value,port) \
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
#define out16(value,port) \
__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
#define out32(value,port) \
__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
#define in8(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
_v; \
})
#define in16(port) ({ \
uint16 _v; \
__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
_v; \
})
#define in32(port) ({ \
uint32 _v; \
__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
_v; \
})
#define out8_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : : "a" (value), "d" (port))
#define in8_p(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : "=a" (_v) : "d" (port)); \
_v; \
})
extern void (*gCpuIdleFunc)(void);
@@ -0,0 +1,123 @@
/*
* Copyright 2018, Jérôme Duval, [email protected].
* Copyright 2002-2009, Axel Dörfler, [email protected].
* Copyright 2012, Alex Smith, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _KERNEL_ARCH_x86_CPUASM_H
#define _KERNEL_ARCH_x86_CPUASM_H
#define nop() __asm__ ("nop"::)
#define x86_read_cr0() ({ \
size_t _v; \
__asm__("mov %%cr0,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr0(value) \
__asm__("mov %0,%%cr0" : : "r" (value))
#define x86_read_cr2() ({ \
size_t _v; \
__asm__("mov %%cr2,%0" : "=r" (_v)); \
_v; \
})
#define x86_read_cr3() ({ \
size_t _v; \
__asm__("mov %%cr3,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr3(value) \
__asm__("mov %0,%%cr3" : : "r" (value))
#define x86_read_cr4() ({ \
size_t _v; \
__asm__("mov %%cr4,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_cr4(value) \
__asm__("mov %0,%%cr4" : : "r" (value))
#define x86_read_dr3() ({ \
size_t _v; \
__asm__("mov %%dr3,%0" : "=r" (_v)); \
_v; \
})
#define x86_write_dr3(value) \
__asm__("mov %0,%%dr3" : : "r" (value))
#define invalidate_TLB(va) \
__asm__("invlpg (%0)" : : "r" (va))
#define wbinvd() \
__asm__ volatile ("wbinvd" : : : "memory")
#define set_ac() \
__asm__ volatile (ASM_STAC : : : "memory")
#define clear_ac() \
__asm__ volatile (ASM_CLAC : : : "memory")
#define xgetbv(reg) ({ \
uint32 low, high; \
__asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
(low | (uint64)high << 32); \
})
#define xsetbv(reg, value) { \
uint32 low = value; uint32 high = value >> 32; \
__asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
#define out8(value,port) \
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
#define out16(value,port) \
__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
#define out32(value,port) \
__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
#define in8(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
_v; \
})
#define in16(port) ({ \
uint16 _v; \
__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
_v; \
})
#define in32(port) ({ \
uint32 _v; \
__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
_v; \
})
#define out8_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : : "a" (value), "d" (port))
#define in8_p(port) ({ \
uint8 _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:" : "=a" (_v) : "d" (port)); \
_v; \
})
#endif /* _KERNEL_ARCH_x86_CPUASM_H */
@@ -0,0 +1,25 @@
/*
* Copyright 2013-2020 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef EFI_BOOT_PLATFORM_EFI_ARCH_CPU_H
#define EFI_BOOT_PLATFORM_EFI_ARCH_CPU_H
#include <SupportDefs.h>
#include <boot/vfs.h>
#ifdef __cplusplus
extern "C" {
#endif
status_t boot_arch_cpu_init(void);
void arch_ucode_load(BootVolume& volume);
#ifdef __cplusplus
}
#endif
#endif /* EFI_BOOT_PLATFORM_EFI_ARCH_CPU_H */
@@ -7,6 +7,9 @@
#include <SupportDefs.h>
#include <boot/vfs.h>
#include "../../../arch/x86/arch_cpuasm.h"
#ifdef __cplusplus
@@ -15,15 +18,13 @@ extern "C" {
void calculate_cpu_conversion_factor(uint8 channel);
status_t boot_arch_cpu_init(void);
void arch_ucode_load(BootVolume& volume);
#ifdef __cplusplus
}
#endif
#include <boot/vfs.h>
void ucode_load(BootVolume& volume);
#endif /* BOOT_ARCH_CPU_H */
+12 -23
View File
@@ -1,13 +1,11 @@
/*
* Copyright 2012, Haiku, Inc.
* Copyright 2012-2020, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ithamar R. Adema <[email protected]>
*/
#include "cpu.h"
#include <OS.h>
#include <boot/platform.h>
#include <boot/stdio.h>
@@ -16,9 +14,9 @@
#include <arch/cpu.h>
#include <arch_kernel.h>
#include <arch_system_info.h>
#include <arch_cpu.h>
#include <string.h>
#define TRACE_CPU
#ifdef TRACE_CPU
# define TRACE(x) dprintf x
@@ -26,6 +24,7 @@
# define TRACE(x) ;
#endif
/*! Detect ARM core version and features.
Please note the fact that ARM7 and ARMv7 are two different things ;)
ARMx is a specific ARM CPU core instance, while ARMvX refers to the
@@ -82,8 +81,8 @@ check_cpu_features()
break;
}
// TODO actually check for VFP support, and maybe there is a better place
// to do this.
// We could check for VFP/NEON support here, but for the moment we only
// really target ARM CPU's with VFP/NEON built-in (cortex-a7+)
if (arch >= ARCH_ARM_v7)
{
// Enable VFP/NEON. We HAVE to do this before the trace call below,
@@ -109,20 +108,6 @@ check_cpu_features()
}
extern "C" void
arch_cpu_memory_read_barrier(void)
{
asm volatile ("" : : : "memory");
}
extern "C" void
arch_cpu_memory_write_barrier(void)
{
asm volatile ("" : : : "memory");
}
extern "C" status_t
boot_arch_cpu_init(void)
{
@@ -132,13 +117,17 @@ boot_arch_cpu_init(void)
return err;
}
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
return B_OK;
}
extern "C" void
arch_ucode_load(BootVolume& volume)
{
// NOP on arm currently
}
extern "C" bigtime_t
system_time()
{
-25
View File
@@ -1,25 +0,0 @@
/*
* Copyright 2004-2005, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef CPU_H
#define CPU_H
#include <SupportDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void arch_cpu_memory_read_barrier(void);
extern void arch_cpu_memory_write_barrier(void);
extern status_t boot_arch_cpu_init(void);
extern void cpu_init(void);
#ifdef __cplusplus
}
#endif
#endif /* CPU_H */
+1 -1
View File
@@ -28,7 +28,7 @@ for platform in [ MultiBootSubDirSetup bios_ia32 efi pxe_ia32 ] {
$(kernelArchSpecificSources)
$(kernelLibArchSpecificSources)
$(librootOsArchSources)
cpu.cpp
arch_cpu.cpp
: -std=c++11 # additional flags
;
@@ -387,3 +387,18 @@ spin(bigtime_t microseconds)
while ((system_time() - time) < microseconds)
asm volatile ("pause;");
}
extern "C" status_t
boot_arch_cpu_init()
{
// Nothing really to init on x86
return B_OK;
}
extern "C" void
arch_ucode_load(BootVolume& volume)
{
ucode_load(volume);
}
+1 -1
View File
@@ -75,5 +75,5 @@ cpu_init()
extern "C" void
platform_load_ucode(BootVolume& volume)
{
ucode_load(volume);
arch_ucode_load(volume);
}
+2 -2
View File
@@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system boot platform efi ;
UsePrivateHeaders [ FDirName kernel boot ] ;
UsePrivateHeaders [ FDirName kernel platform ] ;
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] ;
UsePrivateHeaders [ FDirName kernel boot arch $(TARGET_KERNEL_ARCH) ] ;
SubDirHdrs $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ;
@@ -17,6 +17,7 @@ SubDirHdrs $(HAIKU_TOP) src add-ons kernel partitioning_systems gpt ;
local platform_src =
start.cpp
console.cpp
cpu.cpp
video.cpp
debug.cpp
mmu.cpp
@@ -25,7 +26,6 @@ local platform_src =
timer.cpp
menu.cpp
devices.cpp
cpu.cpp
quirks.cpp
smp.cpp
serial.cpp
@@ -1,5 +1,5 @@
/*
* Copyright, 2019, Haiku, Inc. All rights reserved.
* Copyright, 2019-2020, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -11,7 +11,6 @@
#include <KernelExport.h>
#include <kernel.h>
#include <safemode.h>
#include <boot/stage2.h>
#include <boot/menu.h>
+6 -6
View File
@@ -8,10 +8,10 @@
#include <boot/kernel_args.h>
#include <boot/platform.h>
#include <boot/stage2.h>
#include <boot/vfs.h>
#include <arch/cpu.h>
#ifdef __x86_64__
# include <boot/arch/x86/arch_cpu.h>
#endif
#include <arch_cpu.h>
void
@@ -19,13 +19,13 @@ cpu_init()
{
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
boot_arch_cpu_init();
}
extern "C" void
platform_load_ucode(BootVolume& volume)
{
#ifdef __x86_64__
ucode_load(volume);
#endif
arch_ucode_load(volume);
}