From 6bc6a5428038af19400f8eec7b7dc5c4aa00ddc5 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 31 Oct 2018 23:17:00 +0000 Subject: Add pci_early function to detect Intel stolen memory. On some Intel devices BIOS does not properly reserve memory (called "stolen memory") for the GPU. If the stolen memory is claimed by the OS, functions that depend on stolen memory (like frame buffer compression) can't be used. A function called pci_early_quirks that is called before the virtual memory system is started was added. In Linux, this PCI early quirks function iterates through all PCI slots to check for any device that require quirks. While this more generic solution is preferable I only ported the Intel graphics specific parts because I think my implementation would be too similar to Linux GPL'd solution after looking at the Linux code too much. The code regarding Intel graphics stolen memory was ported from Linux. In the case of Intel graphics stolen memory this pci_early_quirks will read the stolen memory base and size from north bridge registers. The values are stored in global variables that is later read by linuxkpi_gplv2. Linuxkpi stores these values in a Linux-specific structure that is read by the drm driver. Relevant linuxkpi code is here: https://github.com/FreeBSDDesktop/kms-drm/blob/drm-v4.16/linuxkpi/gplv2/src/linux_compat.c#L37 For now, only amd64 arch is suppor ted since that is the only arch supported by the new drm drivers. I was told that Intel GPUs are always located on 0:2:0 so these values are hard coded for now. Note that the structure and early execution of the detection code is not required in its current form, but we expect that the code will be added shortly which fixes the potential BIOS bugs by reserving the stolen range in phys_avail[]. This must be done as early as possible to avoid conflicts with the potential usage of the memory in kernel. Submitted by: Johannes Lundberg Reviewed by: bwidawsk, imp MFC after: 1 week Differential revision: https://reviews.freebsd.org/D16719 Differential revision: https://reviews.freebsd.org/D17775 --- sys/amd64/amd64/machdep.c | 11 +++++++++++ sys/amd64/include/md_var.h | 4 ++++ 2 files changed, 15 insertions(+) (limited to 'sys/amd64') diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index a743d8c63e1b..6e36ae975239 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -317,6 +317,12 @@ cpu_startup(dummy) printf("avail memory = %ju (%ju MB)\n", ptoa((uintmax_t)vm_free_count()), ptoa((uintmax_t)vm_free_count()) / 1048576); +#ifdef DEV_PCI + if (bootverbose && intel_graphics_stolen_base != 0) + printf("intel stolen mem: base %#jx size %ju MB\n", + (uintmax_t)intel_graphics_stolen_base, + (uintmax_t)intel_graphics_stolen_size / 1024 / 1024); +#endif /* * Set up buffers, so they can be used to read disk labels. @@ -1792,6 +1798,11 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) /* now running on new page tables, configured,and u/iom is accessible */ +#ifdef DEV_PCI + /* This call might adjust phys_avail[]. */ + pci_early_quirks(); +#endif + if (late_console) cninit(); diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 5296517595f0..cd8036e25a29 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -43,6 +43,9 @@ extern int hw_ssb_disable; extern int nmi_flush_l1d_sw; extern int syscall_ret_l1d_flush_mode; +extern vm_paddr_t intel_graphics_stolen_base; +extern vm_paddr_t intel_graphics_stolen_size; + /* * The file "conf/ldscript.amd64" defines the symbol "kernphys". Its * value is the physical address at which the kernel is loaded. @@ -79,5 +82,6 @@ void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int ist); void sse2_pagezero(void *addr); struct savefpu *get_pcb_user_save_td(struct thread *td); struct savefpu *get_pcb_user_save_pcb(struct pcb *pcb); +void pci_early_quirks(void); #endif /* !_MACHINE_MD_VAR_H_ */ -- cgit v1.2.3