SFI - Simple Firmware Interface support
Subsystems (4)
Len Brown
reviewerPATCH v2 1/1 SFI - Simple Firmware Interface support
Here is version 2 of the SFI patch series for Linux 2.6.32. This series is based on 2.6.31-rc2, and is available in git:
git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6.git sfi-test
We've tried to respond to all feedback on the v1 series.
In particular, thanks to Ingo Molnar and Andi Kleen for their thorough review.
We followed Andi's advice and deleted the data structure to track tables, and instead we access all table headers in-place. Indeed, this shrunk the memory footprint a bit.
We also now detect and optimize for the common case where all SFI tables fit on a single page.
We added some small bits from the upcoming draft of SFI 0.7, which should be available on http://simplefirmware.org shortly. Of note, we can assert that the SYST shall not cross a 4K boundary.
Thanks,
-Len Brown & Tang-Feng, Intel Open Source Technology Center
--- Documentation/kernel-parameters.txt | 5 + MAINTAINERS | 12 + arch/x86/Kconfig | 4 +- arch/x86/include/asm/io_apic.h | 3 +- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/acpi/boot.c | 22 -- arch/x86/kernel/apic/io_apic.c | 28 ++- arch/x86/kernel/e820.c | 5 + arch/x86/kernel/setup.c | 3 + arch/x86/kernel/sfi.c | 284 +++++++++++++++++++++++++ arch/x86/pci/mmconfig-shared.c | 5 +- drivers/Makefile | 1 + drivers/acpi/tables.c | 3 + drivers/sfi/Kconfig | 16 ++ drivers/sfi/Makefile | 3 + drivers/sfi/sfi_acpi.c | 151 ++++++++++++++ drivers/sfi/sfi_core.c | 387 +++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.h | 44 ++++ include/linux/sfi.h | 198 ++++++++++++++++++ include/linux/sfi_acpi.h | 60 ++++++ init/main.c | 2 + 21 files changed, 1204 insertions(+), 33 deletions(-) create mode 100644 arch/x86/kernel/sfi.c create mode 100644 drivers/sfi/Kconfig create mode 100644 drivers/sfi/Makefile create mode 100644 drivers/sfi/sfi_acpi.c create mode 100644 drivers/sfi/sfi_core.c create mode 100644 drivers/sfi/sfi_core.h create mode 100644 include/linux/sfi.h create mode 100644 include/linux/sfi_acpi.h
commits:
Feng Tang (10):
SFI, x86: add CONFIG_SFI
SFI: document boot param "sfi=off"
SFI: create include/linux/sfi.h
SFI: add core support
ACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hook e820() for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooks
Len Brown (2):
SFI: Simple Firmware Interface - new MAINTAINERS entry
ACPI: check acpi_disabled in acpi_table_parse()
with this log:
commit 7d8801c4e11f26a68fca70798dc40d5f405b4be2
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:34:39 2009 -0400
SFI: add boot-time initialization hooks
There are two SFI boot-time hooks:
sfi_init() maps the SYST using early_ioremap() and validates all the tables.
sfi_init_late() re-maps SYST with ioremap(), and initializes the ACPI extension, if present.
commit 24fe646fcbbd9049850de4ac57cf6a67846b38c4
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:30:32 2009 -0400
SFI, PCI: Hook MMCONFIG
First check ACPI, and if that fails, ask SFI to find the MCFG.
commit 4e176b0f00143e2dfca4480402d3b27b3a0f835f
Author: Len Brown <[email protected]> Date: Tue Jul 7 23:22:58 2009 -0400
ACPI: check acpi_disabled in acpi_table_parse()
Allow consumers of the acpi_table_parse() API
to gracefully handle the acpi_disabled=1 case
without checking the flag themselves.
commit 5ab9dd34acc6209c5b6a3c754075e408e5298a2d
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:15:22 2009 -0400
SFI: Enable SFI to parse ACPI tables
Extend SFI to access standard ACPI tables. (eg. the PCI MCFG) using sfi_acpi_table_parse().
Note that this is _not_ a hybrid ACPI + SFI mode. The platform boots in either ACPI mode or SFI mode.
SFI runs only with acpi_disabled=1, which can be set at build-time via CONFIG_ACPI=n, or at boot time by the failure to find ACPI platform support.
So this extension simply allows SFI-platforms to re-use existing standard table formats that happen to be defined to live in ACPI envelopes.
commit 5bf6b3c7c08a76ea8dc52e9e07728c2958938952
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:11:44 2009 -0400
SFI, x86: hook e820() for memory map initialization
commit 4676b1fee4cae65c678754fbdecae626ac161b81
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:09:19 2009 -0400
SFI: add x86 support
arch/x86/kernel/sfi.c serves the dual-purpose of supporting the SFI core with arch specific code, as well as a home for the arch-specific code that uses SFI.
commit bf8ea7cda3ad3f287f1c9164d366a94eae07a4a5
Author: Feng Tang <[email protected]> Date: Tue Jul 7 23:01:15 2009 -0400
ACPI, x86: remove ACPI dependency on some IO-APIC routines
Both ACPI and SFI x86 systems will use these io_apic routines:
uniq_ioapic_id(u8 id); io_apic_get_unique_id(int ioapic, int apic_id); io_apic_get_version(int ioapic); io_apic_get_redir_entries(int ioapic);
so move the 1st from acpi/boot.c to io_apic.c, and remove the #ifdef ACPI around the other three.
commit 10fb28adc204382cb3b1acc99eabbb369d378a0f
Author: Feng Tang <[email protected]> Date: Tue Jul 7 22:54:22 2009 -0400
SFI: add core support
drivers/sfi/sfi_core.c contains the generic SFI implementation. It has a private header, sfi_core.h, for its own use and the private use of future files in drivers/sfi/
commit 56f1291c60859b65ac62521e7fe4b82e73205ef6
Author: Feng Tang <[email protected]> Date: Tue Jul 7 22:39:49 2009 -0400
SFI: create include/linux/sfi.h
include/linux/include/sfi.h defines everything that customers of SFI need to know in order to use the SFI suport in the kernel.
The primary API is sfi_table_parse(), where a driver or another part of the kernel can supply a handler to parse the named table.
sfi.h also includes the currently defined table signatures and table formats.
commit 57dac60d76c191e3bd72f186833fac01e4c5f8f1
Author: Feng Tang <[email protected]> Date: Tue Jul 7 22:33:09 2009 -0400
SFI: document boot param "sfi=off"
"sfi=off" is analogous to "acpi=off"
In practice, "sfi=off" isn't likely to be very useful, for
1. SFI is used only when ACPI is not available
2. Today's SFI systems are not legacy PC-compatible
ie. "sfi=off" on an ACPI-platform is a NO-OP,
and "sfi=off" on an SFI-platform will likely result in boot failure.
commit d5a8e3203627c313e8fdbf4fa9ac1cb1cdc6706c
Author: Feng Tang <[email protected]> Date: Tue Jul 7 22:30:29 2009 -0400
SFI, x86: add CONFIG_SFI
analogous to ACPI, drivers/sfi/Kconfig is pulled in by arch/x86/Kconfig
commit 8e4a93858bce74ed3080dd607aa471023f1a2737
Author: Len Brown <[email protected]> Date: Tue Jul 7 22:25:46 2009 -0400
SFI: Simple Firmware Interface - new MAINTAINERS entry
CONFIG_SFI=y shall enable the kernel to boot and run optimally on platforms that support the Simple Firmware Interface.
Thanks to Jacob Pan for prototyping the initial Linux SFI support, and to Feng Tang for Linux bring-up and debug both in emulation and on Moorestown hardware.
See http://simplefirmware.org for more information on SFI.
Len Brown
reviewerPATCH 1/12 SFI: Simple Firmware Interface - new MAINTAINERS entry
From: Len Brown <[email protected]>
CONFIG_SFI=y shall enable the kernel to boot and run optimally on platforms that support the Simple Firmware Interface.
Thanks to Jacob Pan for prototyping the initial Linux SFI support, and to Feng Tang for Linux bring-up and debug both in emulation and on Moorestown hardware.
See http://simplefirmware.org for more information on SFI.
--- MAINTAINERS | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
MAINTAINERS +12 -0
@@ -5298,6 +5298,18 @@ L: [email protected] S: Supported F: drivers/pci/hotplug/shpchp* +SIMPLE FIRMWARE INTERFACE (SFI) +P: Len Brown +M: [email protected] +L: [email protected] +W: http://simplefirmware.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6.git +S: Supported +F: arch/x86/kernel/*sfi* +F: drivers/sfi/ +F: include/linux/sfi*.h + + SIMTEC EB110ATX (Chalice CATS) P: Ben Dooks P: Vincent Sanders
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 2/12 SFI, x86: add CONFIG_SFI
In reply to Len BrownFrom: Feng Tang <[email protected]>
analogous to ACPI, drivers/sfi/Kconfig is pulled in by arch/x86/Kconfig
--- arch/x86/Kconfig | 2 ++ drivers/sfi/Kconfig | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 0 deletions(-) create mode 100644 drivers/sfi/Kconfig
arch/x86/Kconfig +2 -0
@@ -1683,6 +1683,8 @@ source "kernel/power/Kconfig" source "drivers/acpi/Kconfig" +source "drivers/sfi/Kconfig" + config X86_APM_BOOT bool default y
drivers/sfi/Kconfig new file +16 -0
@@ -0,0 +1,16 @@ +# +# SFI Configuration +# + +menuconfig SFI + bool "SFI (Simple Firmware Interface) Support" + depends on X86 + default n + ---help--- + The Simple Firmware Interface (SFI) provides a lightweight method + for platform firmware to pass information to the Operating System + via static tables in memory. + + For more information, see http://simplefirmware.org + + Say 'Y' here to enable the kernel to boot on SFI-only platforms.
Signature · 1 line
1.6.0.6
Re: [PATCH 02/12] SFI, x86: add CONFIG_SFI
drivers/sfi/Kconfig line 7
Quoted 9 lines · Len Brown
+++ b/drivers/sfi/Kconfig
drivers/sfi/Kconfig new file +7
-0@@ -0,0 +1,16 @@ +# +# SFI Configuration +# + +menuconfig SFI + bool "SFI (Simple Firmware Interface) Support" + depends on X86
Instead of 'depends on X86' it's cleaner to add a HAVE_ARCH_SFI Kconfig variable to arch/x86/Kconfig, and turn the above into:
depends on HAVE_ARCH_SFI
That will make it easier to enable it on other architectures such as IA64, should the need arise - and it's cleaner in any case.
drivers/sfi/Kconfig line 8
Quoted 1 line
drivers/sfi/Kconfig new file +1
-0+ default n
Kconfig uses 'default n' by default, so this line can be left out.
drivers/sfi/Kconfig line 16
Quoted 8 lines
drivers/sfi/Kconfig new file +8
-0+ ---help--- + The Simple Firmware Interface (SFI) provides a lightweight method + for platform firmware to pass information to the Operating System + via static tables in memory. + + For more information, see http://simplefirmware.org + + Say 'Y' here to enable the kernel to boot on SFI-only platforms.
Nitpick: s/Operating System/Linux kernel
(and even if we want to formulate it in a general way, it should be 'operating system')
Ingo
Len Brown
reviewerPATCH 3/12 SFI: document boot param "sfi=off"
In reply to Len BrownFrom: Feng Tang <[email protected]>
"sfi=off" is analogous to "acpi=off"
In practice, "sfi=off" isn't likely to be very useful, for
1. SFI is used only when ACPI is not available
2. Today's SFI systems are not legacy PC-compatible
ie. "sfi=off" on an ACPI-platform is a NO-OP,
and "sfi=off" on an SFI-platform will likely result in boot failure.
--- Documentation/kernel-parameters.txt | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
Documentation/kernel-parameters.txt +5 -0
@@ -92,6 +92,7 @@ parameter is applicable: SECURITY Different security models are enabled. SELINUX SELinux support is enabled. SERIAL Serial support is enabled. + SFI Simple Firmware Interface SH SuperH architecture is enabled. SMP The kernel is an SMP kernel. SPARC Sparc architecture is enabled.
@@ -2162,6 +2163,10 @@ and is between 256 and 4096 characters. It is defined in the file If enabled at boot time, /selinux/disable can be used later to disable prior to initial policy load. + sfi= [SFI,X86] Simple Firmware Interface + Format: { "off" } + off -- disable SFI + serialnumber [BUGS=X86-32] shapers= [NET]
Signature · 1 line
1.6.0.6
Re: [PATCH 03/12] SFI: document boot param "sfi=off"
Quoted 8 lines · Len Brown
From: Feng Tang <[email protected]>
"sfi=off" is analogous to "acpi=off"
In practice, "sfi=off" isn't likely to be very useful, for
1. SFI is used only when ACPI is not available
2. Today's SFI systems are not legacy PC-compatible
Quoted 8 lines
ie. "sfi=off" on an ACPI-platform is a NO-OP,
and "sfi=off" on an SFI-platform will likely result in boot failure.Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- Documentation/kernel-parameters.txt | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
I think the documentation update should be part of the patch that changes the functionality, so the doc always matches the code.
Bjorn
Quoted 23 lines
Documentation/kernel-parameters.txt +5
-0@@ -92,6 +92,7 @@ parameter is applicable: SECURITY Different security models are enabled. SELINUX SELinux support is enabled. SERIAL Serial support is enabled. + SFI Simple Firmware Interface SH SuperH architecture is enabled. SMP The kernel is an SMP kernel. SPARC Sparc architecture is enabled.@@ -2162,6 +2163,10 @@ and is between 256 and 4096 characters. It is defined in the file If enabled at boot time, /selinux/disable can be used later to disable prior to initial policy load. + sfi= [SFI,X86] Simple Firmware Interface + Format: { "off" } + off -- disable SFI + serialnumber [BUGS=X86-32] shapers= [NET]
Len Brown
reviewerRe: [PATCH 03/12] SFI: document boot param "sfi=off"
Quoted 18 lines · Len Brown
Quoted 8 lines
From: Feng Tang <[email protected]>
"sfi=off" is analogous to "acpi=off"
In practice, "sfi=off" isn't likely to be very useful, for
1. SFI is used only when ACPI is not available
2. Today's SFI systems are not legacy PC-compatibleQuoted 8 lines
ie. "sfi=off" on an ACPI-platform is a NO-OP,
and "sfi=off" on an SFI-platform will likely result in boot failure.Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- Documentation/kernel-parameters.txt | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
Quoted 3 lines
I think the documentation update should be part of the patch that changes the functionality, so the doc always matches the code.
True.
I was somewhat lazy when i generated this patch series from as single patch, and split mainly in groups of files.
Re: sfi=off
I'm actually going to delete this one --
perhaps adding it later when/if it does something useful.
thanks,
-Len Brown, Intel Open Source Technology Center
Len Brown
reviewerPATCH 4/12 SFI: create include/linux/sfi.h
In reply to Len BrownFrom: Feng Tang <[email protected]>
include/linux/include/sfi.h defines everything that customers of SFI need to know in order to use the SFI suport in the kernel.
The primary API is sfi_table_parse(), where a driver or another part of the kernel can supply a handler to parse the named table.
sfi.h also includes the currently defined table signatures and table formats.
--- include/linux/sfi.h | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 198 insertions(+), 0 deletions(-) create mode 100644 include/linux/sfi.h
include/linux/sfi.h new file +198 -0
@@ -0,0 +1,198 @@ +/* sfi.h Simple Firmware Interface */ + +/* +* Copyright (C) 2009, Intel Corp. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions, and the following disclaimer, +* without modification. +* 2. Redistributions in binary form must reproduce at minimum a disclaimer +* substantially similar to the "NO WARRANTY" disclaimer below +* ("Disclaimer") and any redistribution must be conditioned upon +* including a substantially similar Disclaimer requirement for further +* binary redistribution. +* 3. Neither the names of the above-listed copyright holders nor the names +* of any contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* Alternatively, this software may be distributed under the terms of the +* GNU General Public License ("GPL") version 2 as published by the Free +* Software Foundation. +* +* NO WARRANTY +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGES. +*/ + +#ifndef _LINUX_SFI_H +#define _LINUX_SFI_H + +/* Table signatures reserved by the SFI specification */ +#define SFI_SIG_SYST "SYST" +#define SFI_SIG_FREQ "FREQ" +#define SFI_SIG_IDLE "IDLE" +#define SFI_SIG_CPUS "CPUS" +#define SFI_SIG_MTMR "MTMR" +#define SFI_SIG_MRTC "MRTC" +#define SFI_SIG_MMAP "MMAP" +#define SFI_SIG_APIC "APIC" +#define SFI_SIG_XSDT "XSDT" +#define SFI_SIG_WAKE "WAKE" +#define SFI_SIG_SPIB "SPIB" +#define SFI_SIG_I2CB "I2CB" +#define SFI_SIG_GPEM "GPEM" + +#define SFI_ACPI_TABLE (1 << 0) +#define SFI_NORMAL_TABLE (1 << 1) + +#define SFI_SIGNATURE_SIZE 4 +#define SFI_OEM_ID_SIZE 6 +#define SFI_OEM_TABLE_ID_SIZE 8 + +#define SFI_SYST_SEARCH_BEGIN 0x000E0000 +#define SFI_SYST_SEARCH_END 0x000FFFFF + +#define SFI_GET_NUM_ENTRIES (ptable, entry_type) \ + ((ptable->header.length - sizeof(struct sfi_table_header)) / \ + (sizeof(entry_type))) +/* +* Table structures must be byte-packed to match the SFI specification, +* as they are provided by the BIOS. +*/ +struct sfi_table_header { +char signature[SFI_SIGNATURE_SIZE ]; +u32 length; +u8 revision; +u8 checksum; +char oem_id[SFI_OEM_ID_SIZE ]; +char oem_table_id[SFI_OEM_TABLE_ID_SIZE ]; +} __packed; + +struct sfi_table_simple { +struct sfi_table_header header; +u64 pentry[1 ]; +} __packed; + +/* comply with UEFI spec 2.1 */ +struct sfi_mem_entry { +u32 type; +u64 phy_start; +u64 vir_start; +u64 pages; +u64 attrib; +} __packed; + +struct sfi_cpu_table_entry { +u32 apicid; +} __packed; + +struct sfi_cstate_table_entry { +u32 hint;/* MWAIT hint */ +u32 latency;/* latency in ms */ +} __packed; + +struct sfi_apic_table_entry { +u64 phy_addr;/* phy base addr for APIC reg */ +} __packed; + +struct sfi_freq_table_entry { +u32 freq; +u32 latency;/* transition latency in ms */ +u32 ctrl_val;/* value to write to PERF_CTL */ +} __packed; + +struct sfi_wake_table_entry { +u64 phy_addr;/* pointer to where the wake vector locates */ +} __packed; + +struct sfi_timer_table_entry { +u64 phy_addr;/* phy base addr for the timer */ +u32 freq;/* in HZ */ +u32 irq; +} __packed; + +struct sfi_rtc_table_entry { +u64 phy_addr;/* phy base addr for the RTC */ +u32 irq; +} __packed; + +struct sfi_spi_table_entry { +u16 host_num;/* attached to host 0, 1...*/ +u16 cs;/* chip select */ +u16 irq_info; +char name[16 ]; +u8 dev_info[10 ]; +} __packed; + +struct sfi_i2c_table_entry { +u16 host_num; +u16 addr;/* slave addr */ +u16 irq_info; +char name[16 ]; +u8 dev_info[10 ]; +} __packed; + +struct sfi_gpe_table_entry { +u16 logical_id;/* logical id */ +u16 phy_id;/* physical GPE id */ +} __packed; + + +typedef int (*sfi_table_handler ) (struct sfi_table_header *table); + +#ifdef CONFIG_SFI +extern int __init sfi_init_memory_map (void ); +extern void __init sfi_init (void ); +extern int __init sfi_platform_init (void ); +extern void __init sfi_init_late (void ); + +int sfi_table_parse (char *signature,char *oem_id,char *oem_table_id, +uint flag,sfi_table_handler handler); + +extern int sfi_disabled; +static inline void disable_sfi (void ) +{ + sfi_disabled =1 ; +} + +#else /* !CONFIG_SFI */ + +static inline int sfi_init_memory_map (void ) +{ +return -1 ; +} + +static inline void sfi_init (void ) +{ +return ; +} + +static inline void sfi_init_late (void ) +{ +} + +#define sfi_disabled 0 + +static inline int sfi_table_parse (char *signature,char *oem_id, +char *oem_table_id,unsigned int flags, +sfi_table_handler handler) +{ +return -1 ; +} + +#endif /* CONFIG_SFI */ + +#endif /*_LINUX_SFI_H*/
Signature · 1 line
1.6.0.6
Re: [PATCH 04/12] SFI: create include/linux/sfi.h
Quoted 69 lines · Len Brown
From: Feng Tang <[email protected]>
include/linux/include/sfi.hdefines everything that customers of SFI need to know in order to use the SFI suport in the kernel.The primary API is
sfi_table_parse(), where a driver or another part of the kernel can supply a handler to parse the named table.
sfi.halso includes the currently defined table signatures and table formats.Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- include/linux/sfi.h | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 198 insertions(+), 0 deletions(-) create mode 100644 include/linux/sfi.hinclude/linux/sfi.h new file +46
-0@@ -0,0 +1,198 @@ +/* sfi.h Simple Firmware Interface */ + +/* +* Copyright (C) 2009, Intel Corp. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions, and the following disclaimer, +* without modification. +* 2. Redistributions in binary form must reproduce at minimum a disclaimer +* substantially similar to the "NO WARRANTY" disclaimer below +* ("Disclaimer") and any redistribution must be conditioned upon +* including a substantially similar Disclaimer requirement for further +* binary redistribution. +* 3. Neither the names of the above-listed copyright holders nor the names +* of any contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* Alternatively, this software may be distributed under the terms of the +* GNU General Public License ("GPL") version 2 as published by the Free +* Software Foundation. +* +* NO WARRANTY +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGES. +*/ + +#ifndef _LINUX_SFI_H +#define _LINUX_SFI_H + +/* Table signatures reserved by the SFI specification */ +#define SFI_SIG_SYST "SYST" +#define SFI_SIG_FREQ "FREQ" +#define SFI_SIG_IDLE "IDLE"
include/linux/sfi.h line 56
Quoted 10 lines
include/linux/sfi.h new file +10
-0+#define SFI_SIG_CPUS "CPUS" +#define SFI_SIG_MTMR "MTMR" +#define SFI_SIG_MRTC "MRTC" +#define SFI_SIG_MMAP "MMAP" +#define SFI_SIG_APIC "APIC" +#define SFI_SIG_XSDT "XSDT" +#define SFI_SIG_WAKE "WAKE" +#define SFI_SIG_SPIB "SPIB" +#define SFI_SIG_I2CB "I2CB" +#define SFI_SIG_GPEM "GPEM"
Sidenote: these strings, if used in different places, might be instantiated in a duplicated way, bloating the kernel a tiny bit. It might be better to do an intermediate const array and return elements of them.
include/linux/sfi.h line 66
Quoted 10 lines
include/linux/sfi.h new file +10
-0+ +#define SFI_ACPI_TABLE (1 << 0) +#define SFI_NORMAL_TABLE (1 << 1) + +#define SFI_SIGNATURE_SIZE 4 +#define SFI_OEM_ID_SIZE 6 +#define SFI_OEM_TABLE_ID_SIZE 8 + +#define SFI_SYST_SEARCH_BEGIN 0x000E0000 +#define SFI_SYST_SEARCH_END 0x000FFFFF
(see my suggestion about the proper type of these in my other mail)
include/linux/sfi.h line 79
Quoted 13 lines
include/linux/sfi.h new file +13
-0+ +#define SFI_GET_NUM_ENTRIES (ptable, entry_type) \ + ((ptable->header.length - sizeof(struct sfi_table_header)) / \ + (sizeof(entry_type))) +/* +* Table structures must be byte-packed to match the SFI specification, +* as they are provided by the BIOS. +*/ +struct sfi_table_header { +char signature[SFI_SIGNATURE_SIZE ]; +u32 length; +u8 revision; +u8 checksum;
These could be abbreviated with common terms:
s/signature/sig
s/length/len
s/revision/rev
s/checksum/csum
include/linux/sfi.h line 92
Quoted 13 lines
include/linux/sfi.h new file +13
-0+char oem_id[SFI_OEM_ID_SIZE ]; +char oem_table_id[SFI_OEM_TABLE_ID_SIZE ]; +} __packed; + +struct sfi_table_simple { +struct sfi_table_header header; +u64 pentry[1 ]; +} __packed; + +/* comply with UEFI spec 2.1 */ +struct sfi_mem_entry { +u32 type; +u64 phy_start;
s/phy_start/phys_start
include/linux/sfi.h line 93
Quoted 1 line
include/linux/sfi.h new file +1
-0+u64 vir_start;
s/vir_start/virt_start
include/linux/sfi.h line 99
Quoted 6 lines
include/linux/sfi.h new file +6
-0+u64 pages; +u64 attrib; +} __packed; + +struct sfi_cpu_table_entry { +u32 apicid;
s/apicid/apic_id
(i realize that apicid is still the commonly used one in arch/x86, but that's not a reason to continue that bad practice with new code.)
include/linux/sfi.h line 108
Quoted 9 lines
include/linux/sfi.h new file +9
-0+} __packed; + +struct sfi_cstate_table_entry { +u32 hint;/* MWAIT hint */ +u32 latency;/* latency in ms */ +} __packed; + +struct sfi_apic_table_entry { +u64 phy_addr;/* phy base addr for APIC reg */
s/phy_addr/phys_addr
include/linux/sfi.h line 112
Quoted 4 lines
include/linux/sfi.h new file +4
-0+} __packed; + +struct sfi_freq_table_entry { +u32 freq;
is this in Hz or in kHz? (should be reflected in the name: say freq_khz)
I suspect it's HZ here - but that's not unambiguous - often cpufreq settings are in khz.
include/linux/sfi.h line 114
Quoted 2 lines
include/linux/sfi.h new file +2
-0+u32 latency;/* transition latency in ms */ +u32 ctrl_val;/* value to write to PERF_CTL */
PERF_CTL is an u64 MSR.
include/linux/sfi.h line 118
Quoted 4 lines
include/linux/sfi.h new file +4
-0+} __packed; + +struct sfi_wake_table_entry { +u64 phy_addr;/* pointer to where the wake vector locates */
s/phy_addr/phys_addr
include/linux/sfi.h line 122
Quoted 4 lines
include/linux/sfi.h new file +4
-0+} __packed; + +struct sfi_timer_table_entry { +u64 phy_addr;/* phy base addr for the timer */
s/phy_addr/phys_addr
include/linux/sfi.h line 123
Quoted 1 line
include/linux/sfi.h new file +1
-0+u32 freq;/* in HZ */
So we limit frequency to ~4 GHz?
include/linux/sfi.h line 128
Quoted 5 lines
include/linux/sfi.h new file +5
-0+u32 irq; +} __packed; + +struct sfi_rtc_table_entry { +u64 phy_addr;/* phy base addr for the RTC */
s/phy_addr/phys_addr
Quoted 12 lines
include/linux/sfi.h new file +12
-0+u32 irq; +} __packed; + +struct sfi_spi_table_entry { +u16 host_num;/* attached to host 0, 1...*/ +u16 cs;/* chip select */ +u16 irq_info; +char name[16 ]; +u8 dev_info[10 ]; +} __packed; + +struct sfi_i2c_table_entry {
include/linux/sfi.h line 150
Quoted 10 lines
include/linux/sfi.h new file +10
-0+u16 host_num; +u16 addr;/* slave addr */ +u16 irq_info; +char name[16 ]; +u8 dev_info[10 ]; +} __packed; + +struct sfi_gpe_table_entry { +u16 logical_id;/* logical id */ +u16 phy_id;/* physical GPE id */
s/phy_id/phys_id
include/linux/sfi.h line 156
Quoted 6 lines
include/linux/sfi.h new file +6
-0+} __packed; + + +typedef int (*sfi_table_handler ) (struct sfi_table_header *table); + +#ifdef CONFIG_SFI
(stray tab.)
include/linux/sfi.h line 163
Quoted 7 lines
include/linux/sfi.h new file +7
-0+extern int __init sfi_init_memory_map (void ); +extern void __init sfi_init (void ); +extern int __init sfi_platform_init (void ); +extern void __init sfi_init_late (void ); + +int sfi_table_parse (char *signature,char *oem_id,char *oem_table_id, +uint flag,sfi_table_handler handler);
some prototypes come with externs ... some without. Please use one variant.
Quoted 8 lines
include/linux/sfi.h new file +8
-0+ +extern int sfi_disabled; +static inline void disable_sfi (void ) +{ + sfi_disabled =1 ; +} + +#else /* !CONFIG_SFI */
include/linux/sfi.h line 181
Quoted 10 lines
include/linux/sfi.h new file +10
-0+ +static inline int sfi_init_memory_map (void ) +{ +return -1 ; +} + +static inline void sfi_init (void ) +{ +return ; +}
no need for that return.
Thanks,
Ingo
Len Brown
reviewerPATCH 5/12 SFI: add core support
In reply to Len BrownFrom: Feng Tang <[email protected]>
drivers/sfi/sfi_core.c contains the generic SFI implementation. It has a private header, sfi_core.h, for its own use and the private use of future files in drivers/sfi/
--- drivers/Makefile | 1 + drivers/sfi/Makefile | 1 + drivers/sfi/sfi_core.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.h | 44 ++++++ 4 files changed, 431 insertions(+), 0 deletions(-) create mode 100644 drivers/sfi/Makefile create mode 100644 drivers/sfi/sfi_core.c create mode 100644 drivers/sfi/sfi_core.h
drivers/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ obj-$(CONFIG_ACPI) += acpi/ +obj-$(CONFIG_SFI) += sfi/ # PnP must come after ACPI since it will eventually need to check if acpi # was used and do nothing if so obj-$(CONFIG_PNP) += pnp/
drivers/sfi/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-y += sfi_core.o
drivers/sfi/sfi_core.c new file +385 -0
385 lines not on this page · raw message
drivers/sfi/sfi_core.h new file +44 -0
44 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Re: [PATCH 05/12] SFI: add core support
Quoted 96 lines · Len Brown
From: Feng Tang <[email protected]>
drivers/sfi/sfi_core.ccontains the generic SFI implementation. It has a private header,sfi_core.h, for its own use and the private use of future files indrivers/sfi/Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- drivers/Makefile | 1 + drivers/sfi/Makefile | 1 + drivers/sfi/sfi_core.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.h | 44 ++++++ 4 files changed, 431 insertions(+), 0 deletions(-) create mode 100644 drivers/sfi/Makefile create mode 100644 drivers/sfi/sfi_core.c create mode 100644 drivers/sfi/sfi_core.hdrivers/Makefile +1
-0@@ -11,6 +11,7 @@ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ obj-$(CONFIG_ACPI) += acpi/ +obj-$(CONFIG_SFI) += sfi/ # PnP must come after ACPI since it will eventually need to check if acpi # was used and do nothing if so obj-$(CONFIG_PNP) += pnp/drivers/sfi/Makefile new file +1
-0@@ -0,0 +1 @@ +obj-y += sfi_core.odrivers/sfi/sfi_core.c new file +53
-0@@ -0,0 +1,385 @@ +/* sfi_core.c Simple Firmware Interface - core internals */ + +/* +* Copyright (C) 2009, Intel Corp. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions, and the following disclaimer, +* without modification. +* 2. Redistributions in binary form must reproduce at minimum a disclaimer +* substantially similar to the "NO WARRANTY" disclaimer below +* ("Disclaimer") and any redistribution must be conditioned upon +* including a substantially similar Disclaimer requirement for further +* binary redistribution. +* 3. Neither the names of the above-listed copyright holders nor the names +* of any contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* Alternatively, this software may be distributed under the terms of the +* GNU General Public License ("GPL") version 2 as published by the Free +* Software Foundation. +* +* NO WARRANTY +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGES. +*/ + +#define KMSG_COMPONENT "SFI" +#define pr_fmt (fmt) KMSG_COMPONENT ": " fmt + +#include <linux/bootmem.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/acpi.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/smp.h> +#include <linux/sfi.h>
drivers/sfi/sfi_core.c line 63
Quoted 10 lines
drivers/sfi/sfi_core.c new file +10
-0+ +#include <asm/pgtable.h> + +#include "sfi_core.h" + +#define ON_SAME_PAGE (addr1, addr2) \ + (((unsigned long)(addr1) & PAGE_MASK) == \ + ((unsigned long)(addr2) & PAGE_MASK)) +#define TABLE_ON_PAGE (page, table, size) (ON_SAME_PAGE(page, table) && \ + ON_SAME_PAGE(page, table + size))
these two should be written in C, not CPP.
Quoted 79 lines
drivers/sfi/sfi_core.c new file +79
-0+int sfi_disabled__read_mostly ; +EXPORT_SYMBOL (sfi_disabled); + +static u64 syst_pa__read_mostly ; +static struct sfi_table_simple *syst_va__read_mostly ; + +/* +* FW creates and saves the SFI tables in memory. When these tables get +* used, they may need to be mapped to virtual address space, and the mapping +* can happen before or after the ioremap() is ready, so a flag is needed +* to indicating this +*/ +static u32 sfi_use_ioremap__read_mostly ; + +static void __iomem *sfi_map_memory (u64 phys,u32 size) +{ +if (!phys || !size) +return NULL ; + +if (sfi_use_ioremap) +return ioremap (phys, size); +else +return early_ioremap (phys, size); +} + +static void sfi_unmap_memory (void __iomem *virt,u32 size) +{ +if (!virt || !size) +return ; + +if (sfi_use_ioremap) +iounmap (virt); +else +early_iounmap (virt, size); +} + +static void sfi_print_table_header (unsigned long long pa, +struct sfi_table_header *header) +{ +pr_info ("%4.4s %llX, %04X (v%d %6.6s %8.8s)\n" , + header->signature, pa, + header->length, header->revision, header->oem_id, + header->oem_table_id); +} + +/* +* sfi_verify_table() +* sanity check table lengh, calculate checksum +*/ +static __init int sfi_verify_table (struct sfi_table_header *table) +{ + +u8 checksum =0 ; +u8 *puchar = (u8 *)table; +u32 length = table->length; + +/* Sanity check table length against arbitrary 1MB limit */ +if (length >0x100000 ) { +pr_err ("Invalid table length 0x%x\n" , length); +return -1 ; + } + +while (length--) + checksum += *puchar++; + +if (checksum) { +pr_err ("Checksum %2.2X should be %2.2X\n" , + table->checksum, table->checksum - checksum); +return -1 ; + } +return 0 ; +} + +/* +* sfi_map_table() +* +* Return address of mapped table +* Check for common case that we can re-use mapping to SYST, +* which requires syst_pa, syst_va to be initialized.
drivers/sfi/sfi_core.c line 153
Quoted 10 lines
drivers/sfi/sfi_core.c new file +10
-0+*/ +struct sfi_table_header *sfi_map_table (u64 pa) +{ +struct sfi_table_header *th; +u32 length; + +if (!TABLE_ON_PAGE (syst_pa, pa,sizeof (struct sfi_table_header ))) + th =sfi_map_memory (pa,sizeof (struct sfi_table_header )); +else + th = (void *)syst_va - (syst_pa - pa);
The '- (syst_pa - pa)' arithmetics is correct but rather unreadable
- it should be something like:
th = (void *)syst_va + (pa - syst_pa);
To show that we return an offset into the SYST table - instead of the double negation.
drivers/sfi/sfi_core.c line 159
Quoted 6 lines
drivers/sfi/sfi_core.c new file +6
-0+ +/* If table fits on same page as its header, we are done */ +if (TABLE_ON_PAGE (th, th, th->length)) +return th; + +/* entire table does not fit on same page as SYST */
Nit: please capitalize comments consistently, by starting them with a capital letter.
drivers/sfi/sfi_core.c line 164
Quoted 5 lines
drivers/sfi/sfi_core.c new file +5
-0+ length = th->length; +if (!TABLE_ON_PAGE (syst_pa, pa,sizeof (struct sfi_table_header ))) +sfi_unmap_memory (th,sizeof (struct sfi_table_header )); + +return sfi_map_memory (pa, length);
tricky.
Quoted 41 lines
drivers/sfi/sfi_core.c new file +41
-0+} + +/* + * sfi_unmap_table() + * + * undoes effect of sfi_map_table() by unmapping table + * if it did not completely fit on same page as SYST. + */ +void sfi_unmap_table(struct sfi_table_header *th) +{ + if (!TABLE_ON_PAGE(syst_va, th, th->length)) + sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->length) ? + sizeof(*th) : th->length); +} + +/* + * sfi_get_table() + * + * Search SYST for the specified table. + * return the mapped table + */ +static struct sfi_table_header *sfi_get_table(char *signature, char *oem_id, + char *oem_table_id, unsigned int flags) +{ + struct sfi_table_header *th; + u32 tbl_cnt, i; + + tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64); + + for (i = 0; i < tbl_cnt; i++) { + th = sfi_map_table(syst_va->pentry[i]); + if (!th) + return NULL; + + if (strncmp(th->signature, signature, SFI_SIGNATURE_SIZE)) + goto loop_continue; + + if (oem_id && strncmp(th->oem_id, oem_id, SFI_OEM_ID_SIZE)) + goto loop_continue; + + if (oem_table_id && strncmp(th->oem_table_id, oem_table_id,
drivers/sfi/sfi_core.c line 215
Quoted 10 lines
drivers/sfi/sfi_core.c new file +10
-0+ SFI_OEM_TABLE_ID_SIZE)) + goto loop_continue; + +return th;/* success */ +loop_continue: +sfi_unmap_table (th); + } + +return NULL ; +}
This loop should be cleaned up in the same fashion as i suggested for sfi_acpi_get_table().
drivers/sfi/sfi_core.c line 222
Quoted 7 lines
drivers/sfi/sfi_core.c new file +7
-0+ +void sfi_put_table (struct sfi_table_header *table) +{ +if (!ON_SAME_PAGE (((void *)table + table->length), + (void *)syst_va + syst_va->header.length) + && !ON_SAME_PAGE (table, syst_va)) +sfi_unmap_memory (table, table->length);
syst_va should probably be a void * to begin with - that avoids the second cast.
I'm quite uneasy about the many open-coded ON_SAME_PAGE() conditions. That logic should perhaps be in sfi_map/unmap_memory() instead? (with an additional 'finegrained_len' argument to it or so.)
Quoted 11 lines
drivers/sfi/sfi_core.c new file +11
-0+} + +/* find table with signature, run handler on it */ +int sfi_table_parse (char *signature,char *oem_id,char *oem_table_id, +unsigned int flags,sfi_table_handler handler) +{ +int ret =0 ; +struct sfi_table_header *table =NULL ; + +if (sfi_disabled || !handler || !signature) +return -EINVAL ;
drivers/sfi/sfi_core.c line 243
Quoted 10 lines
drivers/sfi/sfi_core.c new file +10
-0+ + table =sfi_get_table (signature, oem_id, oem_table_id, flags); +if (!table) +return -EINVAL ; + + ret =handler (table); +sfi_put_table (table); +return ret; +} +EXPORT_SYMBOL_GPL (sfi_table_parse);
the error conditions could be written cleaner and shorter as:
int sfi_table_parse(char *signature, char *oem_id, char *oem_table_id,
unsigned int flags, sfi_table_handler handler)
{
struct sfi_table_header *table = NULL;
int ret = -EINVAL;
if (sfi_disabled || !handler || !signature)
goto err;
table = sfi_get_table(signature, oem_id, oem_table_id, flags);
if (!table)
goto err;
ret = handler(table);
sfi_put_table(table);
err:
return ret;
}Thanks,
Ingo
Len Brown
reviewerPATCH 6/12 ACPI, x86: remove ACPI dependency on some IO-APIC routines
In reply to Len BrownFrom: Feng Tang <[email protected]>
Both ACPI and SFI x86 systems will use these io_apic routines:
uniq_ioapic_id(u8 id);io_apic_get_unique_id(int ioapic, int apic_id);io_apic_get_version(int ioapic);io_apic_get_redir_entries(int ioapic);
so move the 1st from acpi/boot.c to io_apic.c, and remove the #ifdef ACPI around the other three.
--- arch/x86/include/asm/io_apic.h | 3 +-- arch/x86/kernel/acpi/boot.c | 22 ---------------------- arch/x86/kernel/apic/io_apic.c | 28 +++++++++++++++++++++------- 3 files changed, 22 insertions(+), 31 deletions(-)
arch/x86/include/asm/io_apic.h +1 -2
@@ -150,11 +150,10 @@ extern int timer_through_8259;#define io_apic_assign_pci_irqs \ (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) -#ifdef CONFIG_ACPI +extern u8 uniq_ioapic_id (u8 id);extern int io_apic_get_unique_id (int ioapic,int apic_id);extern int io_apic_get_version (int ioapic);extern int io_apic_get_redir_entries (int ioapic); -#endif /* CONFIG_ACPI */ struct io_apic_irq_attr ; extern int io_apic_set_pci_routing(struct device *dev, int irq,
arch/x86/kernel/acpi/boot.c +0 -22
@@ -863,28 +863,6 @@ int mp_find_ioapic_pin(int ioapic, int gsi)return gsi - mp_ioapic_routing[ioapic].gsi_base; } -static u8 __init uniq_ioapic_id (u8 id) -{ -#ifdef CONFIG_X86_32 -if ((boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL ) && - !APIC_XAPIC (apic_version[boot_cpu_physical_apicid])) -return io_apic_get_unique_id (nr_ioapics, id); -else -return id; -#else -int i; -DECLARE_BITMAP (used,256 ); -bitmap_zero (used,256 ); -for (i =0 ; i < nr_ioapics; i++) { -struct mpc_ioapic *ia = &mp_ioapics[i]; -__set_bit (ia->apicid, used); - } -if (!test_bit (id, used)) -return id; -return find_first_zero_bit (used,256 ); -#endif -} -static int bad_ioapic (unsigned long address) {if (nr_ioapics >=MAX_IO_APICS ) {
arch/x86/kernel/apic/io_apic.c +21 -7
@@ -3944,11 +3944,27 @@ int io_apic_set_pci_routing(struct device *dev, int irq,return __io_apic_set_pci_routing (dev, irq, irq_attr); } -/* -------------------------------------------------------------------------- -ACPI-based IOAPIC Configuration --------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI +u8 __init uniq_ioapic_id (u8 id) +{ +#ifdef CONFIG_X86_32 +if ((boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL ) && + !APIC_XAPIC (apic_version[boot_cpu_physical_apicid])) +return io_apic_get_unique_id (nr_ioapics, id); +else +return id; +#else +int i; +DECLARE_BITMAP (used,256 ); +bitmap_zero (used,256 ); +for (i =0 ; i < nr_ioapics; i++) { +struct mpc_ioapic *ia = &mp_ioapics[i]; +__set_bit (ia->apicid, used); + } +if (!test_bit (id, used)) +return id; +return find_first_zero_bit (used,256 ); +#endif +}#ifdef CONFIG_X86_32 int __init io_apic_get_unique_id (int ioapic,int apic_id)
@@ -4057,8 +4073,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)return 0 ; } -#endif /* CONFIG_ACPI */ -/* * This function currently is only a helper for the i386 smp boot process where * we need to reprogram the ioredtbls to cater for the cpus which have come online
Signature · 1 line
1.6.0.6
Re: [PATCH 06/12] ACPI, x86: remove ACPI dependency on some IO-APIC routines
Quoted 5 lines · Len Brown
From: Feng Tang <[email protected]>
Both ACPI and SFI x86 systems will use these
io_apicroutines:
uniq_ioapic_id(u8 id);
While touching this code please also fix the misnomer:
s/uniq_ioapic_id/unique_ioapic_id
Thanks,
Ingo
Len Brown
reviewerPATCH 7/12 SFI: add x86 support
In reply to Len BrownFrom: Feng Tang <[email protected]>
arch/x86/kernel/sfi.c serves the dual-purpose of supporting the SFI core with arch specific code, as well as a home for the arch-specific code that uses SFI.
--- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/sfi.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.c | 2 +- 3 files changed, 286 insertions(+), 1 deletions(-) create mode 100644 arch/x86/kernel/sfi.c
arch/x86/kernel/Makefile +1 -0
@@ -53,6 +53,7 @@ obj-y += step.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ obj-y += acpi/ +obj-$(CONFIG_SFI) += sfi.o obj-y += reboot.o obj-$(CONFIG_MCA) += mca_32.o obj-$(CONFIG_X86_MSR) += msr.o
arch/x86/kernel/sfi.c new file +284 -0
284 lines not on this page · raw message
drivers/sfi/sfi_core.c +1 -1
@@ -350,7 +350,7 @@ void __init sfi_init(void)pr_info ("Simple Firmware Interface v0.7 http://simplefirmware.org\n" ); -if (sfi_find_syst () ||sfi_parse_syst ()) +if (sfi_find_syst () ||sfi_parse_syst () ||sfi_platform_init ())disable_sfi ();return ;
Signature · 1 line
1.6.0.6
Re: [PATCH 07/12] SFI: add x86 support
Quoted 91 lines · Len Brown
From: Feng Tang <[email protected]>
arch/x86/kernel/sfi.cserves the dual-purpose of supporting the SFI core with arch specific code, as well as a home for the arch-specific code that uses SFI.Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/sfi.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.c | 2 +- 3 files changed, 286 insertions(+), 1 deletions(-) create mode 100644 arch/x86/kernel/sfi.carch/x86/kernel/Makefile +1
-0@@ -53,6 +53,7 @@ obj-y += step.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ obj-y += acpi/ +obj-$(CONFIG_SFI) += sfi.o obj-y += reboot.o obj-$(CONFIG_MCA) += mca_32.o obj-$(CONFIG_X86_MSR) += msr.oarch/x86/kernel/sfi.c new file +58
-0@@ -0,0 +1,284 @@ +/* +* sfi.c - SFI Boot Support (refer acpi/boot.c) +* +* Copyright (C) 2008-2009 Intel Corporation +* +* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +#define KMSG_COMPONENT "SFI" +#define pr_fmt (fmt) KMSG_COMPONENT ": " fmt + +#include <linux/bootmem.h> +#include <linux/cpumask.h> +#include <linux/module.h> +#include <linux/acpi.h> +#include <linux/init.h> +#include <linux/efi.h> +#include <linux/irq.h> +#include <linux/sfi.h> +#include <linux/io.h> + +#include <asm/io_apic.h> +#include <asm/pgtable.h> +#include <asm/mpspec.h> +#include <asm/setup.h> +#include <asm/apic.h> +#include <asm/e820.h> + +#ifdef CONFIG_X86_LOCAL_APIC +static unsigned long sfi_lapic_addr__initdata =APIC_DEFAULT_PHYS_BASE ; +#endif + +#ifdef CONFIG_X86_IO_APIC +static struct mp_ioapic_routing { +int gsi_base; +int gsi_end; +} mp_ioapic_routing[MAX_IO_APICS ]; +#endif + +static __init struct sfi_table_simple *sfi_early_find_syst (void ) +{ +unsigned long i;
arch/x86/kernel/sfi.c line 68
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+char *pchar = (char *)SFI_SYST_SEARCH_BEGIN ; + +/* SFI spec defines the SYST starts at a 16-byte boundary */ +for (i =0 ;SFI_SYST_SEARCH_BEGIN + i <SFI_SYST_SEARCH_END ; i +=16 ) { +if (!strncmp (SFI_SIG_SYST , pchar,SFI_SIGNATURE_SIZE )) +return (struct sfi_table_simple *) + (SFI_SYST_SEARCH_BEGIN + i); + + pchar +=16 ; + }
Hm, this loop seems a bit confused about how it wants to iterate over a range of addresses.
SFI_SYST_SEARCH_BEGIN and END should probably have a void * basic type, which would allow a _much_ cleaner loop like this:
static __init struct sfi_table_simple *sfi_early_find_syst(void)
{
/* SFI spec defines the SYST starts at a 16-byte boundary */
for (p = SFI_SYST_SEARCH_BEGIN; p < SFI_SYST_SEARCH_END, p += 16) {
if (!strncmp(SFI_SIG_SYST, p, SFI_SIGNATURE_SIZE))
return p;
}
return NULL;
}And this is a general observation for the other patches as well: if you anywhere do a C type cast please double check whether you really need to do it. In 90% of the cases it's a sign of some badness, in 99% of the cases it's a source of fragility, and in 99.9% of the cases it can be avoided by restructuring the code.
I saw a handful of other cases where it's really avoidable.
Quoted 6 lines
arch/x86/kernel/sfi.c new file +6
-0+/* +* called in a early boot phase before the paging table is created, +* setup a mmap table in e820 format +*/ +int __init sfi_init_memory_map (void ) +{
arch/x86/kernel/sfi.c line 87
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+struct sfi_table_simple *syst, *mmapt; +struct sfi_mem_entry *mentry; +unsigned long long start, end, size; +int i, num, type, tbl_cnt; +u64 *pentry; + +if (sfi_disabled) +return -1 ; + +/* first search the syst table */
Nit: s/syst/SYST in the comment text - to stay in line with how we refer to these firmware tables.
arch/x86/kernel/sfi.c line 93
Quoted 6 lines
arch/x86/kernel/sfi.c new file +6
-0+ syst =sfi_early_find_syst (); +if (!syst) +return -1 ; + + tbl_cnt = (syst->header.length -sizeof (struct sfi_table_header )) / +sizeof (u64);
We have a helper for this, SFI_GET_NUM_ENTRIES(), please use it as SFI_GET_NUM_ENTRIES(syst, u64) or so.
arch/x86/kernel/sfi.c line 104
Quoted 11 lines
arch/x86/kernel/sfi.c new file +11
-0+ pentry = syst->pentry; + +/* walk through the syst to search the mmap table */ + mmapt =NULL ; +for (i =0 ; i < tbl_cnt; i++) { +if (!strncmp (SFI_SIG_MMAP , (char *)(u32)*pentry,4 )) { + mmapt = (struct sfi_table_simple *)(u32)*pentry; +break ; + } + pentry++; + }
This loop does a double type cast - which already shows that we do something weird here. Firstly, this will trigger a warning on 64-bit builds. Secondly, it's cast twice - to different target types.
Thirdly, the double cast itself discards the high 32 bits of the value. This is pretty bad as it allows the firmware to pass in some bogus value there and we could build a dependency on it.
Quoted 8 lines
arch/x86/kernel/sfi.c new file +8
-0+if (!mmapt) { +pr_warning ("could not find a valid memory map table\n" ); +return -1 ; + } + +/* refer copy_e820_memory() */ + num = SFI_GET_NUM_ENTRIES(mmapt, struct sfi_mem_entry); + mentry = (struct sfi_mem_entry *)mmapt->pentry;
arch/x86/kernel/sfi.c line 122
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+for (i =0 ; i < num; i++) { + start = mentry->phy_start; + size = mentry->pages <<PAGE_SHIFT ; + end = start + size; + +if (start > end) +return -1 ; + +pr_debug ("start = 0x%08x end = 0x%08x type = %d\n" , + (u32 )start, (u32 )end, mentry->type);
DEBUG is not defined at the top of the file so this is dead code.
Quoted 14 lines
arch/x86/kernel/sfi.c new file +14
-0+/* translate SFI mmap type to E820 map type */ +switch (mentry->type) { +case EFI_CONVENTIONAL_MEMORY : + type =E820_RAM ; +break ; +case EFI_UNUSABLE_MEMORY : + type =E820_UNUSABLE ; +break ; +default : + type =E820_RESERVED ; + } + +e820_add_region (start, size, type); + mentry++;
arch/x86/kernel/sfi.c line 147
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+ } + +return 0 ; +} + +#ifdef CONFIG_X86_LOCAL_APIC +void __init mp_sfi_register_lapic_address (unsigned long address) +{ + mp_lapic_addr = address; +set_fixmap_nocache (FIX_APIC_BASE , mp_lapic_addr);
Please put newlines after local variable definition blocks.
Quoted 37 lines
arch/x86/kernel/sfi.c new file +37
-0+ +if (boot_cpu_physical_apicid ==-1U ) + boot_cpu_physical_apicid =read_apic_id (); + +pr_debug ("Boot CPU = %d\n" , boot_cpu_physical_apicid); +} + +/* All CPUs enumerated by SFI must be present and enabled */ +void __cpuinit mp_sfi_register_lapic (u8 id) +{ +int boot_cpu =0 ; + +if (MAX_APICS - id <=0 ) { +pr_warning ("Processor #%d invalid (max %d)\n" , + id,MAX_APICS ); +return ; + } + +if (id == boot_cpu_physical_apicid) + boot_cpu =1 ; +pr_info ("registering lapic[%d]\n" , id); + +generic_processor_info (id,GET_APIC_VERSION (apic_read (APIC_LVR ))); +} + +static int __init sfi_parse_cpus (struct sfi_table_header *table) +{ +struct sfi_table_simple *sb; +struct sfi_cpu_table_entry *pentry; +int i; +int cpu_num; + + sb = (struct sfi_table_simple *)table; + cpu_num = SFI_GET_NUM_ENTRIES(sb, struct sfi_cpu_table_entry); + pentry = (struct sfi_cpu_table_entry *)sb->pentry; + +for (i =0 ; i < cpu_num; i++) {
arch/x86/kernel/sfi.c line 194
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+mp_sfi_register_lapic (pentry->apicid); + pentry++; + } + + smp_found_config =1 ; +return 0 ; +} +#endif /* CONFIG_X86_LOCAL_APIC */ + +#ifdef CONFIG_X86_IO_APIC
(stray tab.)
arch/x86/kernel/sfi.c line 199
Quoted 5 lines
arch/x86/kernel/sfi.c new file +5
-0+void __init mp_sfi_register_ioapic (u8 id,u32 paddr) +{ +int idx =0 ; +int tmpid; +static u32 gsi_base;
I think this static variable should be outside of this function - so that it's apparent at a glance that it persists.
arch/x86/kernel/sfi.c line 204
Quoted 5 lines
arch/x86/kernel/sfi.c new file +5
-0+ +if (nr_ioapics >=MAX_IO_APICS ) { +pr_err ("ERROR: Max # of I/O APICs (%d) exceeded " +"(found %d)\n" ,MAX_IO_APICS , nr_ioapics); +panic ("Recompile kernel with bigger MAX_IO_APICS!\n" );
We should fail more gracefully here i think - print a warning and continue. The system might not boot ... or it might, with a few devices not operational.
Quoted 14 lines
arch/x86/kernel/sfi.c new file +14
-0+ } +if (!paddr) { +pr_warning ("WARNING: Bogus (zero) I/O APIC address" +" found in MADT table, skipping!\n" ); +return ; + } + + idx = nr_ioapics; + + mp_ioapics[idx].type =MP_IOAPIC ; + mp_ioapics[idx].flags =MPC_APIC_USABLE ; + mp_ioapics[idx].apicaddr = paddr; + +set_fixmap_nocache (FIX_IO_APIC_BASE_0 + idx, paddr);
arch/x86/kernel/sfi.c line 228
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+ tmpid =uniq_ioapic_id (id); +if (tmpid ==-1 ) +return ; + + mp_ioapics[idx].apicid = tmpid; +#ifdef CONFIG_X86_32 + mp_ioapics[idx].apicver =io_apic_get_version (idx); +#else + mp_ioapics[idx].apicver =0 ; +#endif
Why is this define needed? io_apic_get_version() exists on 64-bit as well.
Quoted 43 lines
arch/x86/kernel/sfi.c new file +43
-0+ +/* +* Build basic GSI lookup table to facilitate gsi->io_apic lookups +* and to prevent reprogramming of IOAPIC pins (PCI GSIs). +*/ + mp_ioapic_routing[idx].gsi_base = gsi_base; + mp_ioapic_routing[idx].gsi_end = gsi_base + +io_apic_get_redir_entries (idx); + gsi_base = mp_ioapic_routing[idx].gsi_end +1 ; + +pr_info ("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " +"GSI %d-%d\n" , + idx, mp_ioapics[idx].apicid, + mp_ioapics[idx].apicver, (u32 )mp_ioapics[idx].apicaddr, + mp_ioapic_routing[idx].gsi_base, + mp_ioapic_routing[idx].gsi_end); + + nr_ioapics++; +} + +static int __init sfi_parse_ioapic (struct sfi_table_header *table) +{ +struct sfi_table_simple *sb; +struct sfi_apic_table_entry *pentry; +int i, num; + + sb = (struct sfi_table_simple *)table; + num = SFI_GET_NUM_ENTRIES(sb, struct sfi_apic_table_entry); + pentry = (struct sfi_apic_table_entry *)sb->pentry; + +for (i =0 ; i < num; i++) { +mp_sfi_register_ioapic (i, pentry->phy_addr); + pentry++; + } + +WARN (pic_mode,KERN_WARNING +"SFI: pic_mod shouldn't be 1 when IOAPIC table is present\n" ); + pic_mode =0 ; +return 0 ; +} +#endif /* CONFIG_X86_IO_APIC */ + +/*
arch/x86/kernel/sfi.c line 281
Quoted 10 lines
arch/x86/kernel/sfi.c new file +10
-0+* sfi_platform_init(): register lapics & io-apics +*/ +int __init sfi_platform_init (void ) +{ +#ifdef CONFIG_X86_LOCAL_APIC +mp_sfi_register_lapic_address (sfi_lapic_addr); +sfi_table_parse (SFI_SIG_CPUS ,NULL ,NULL ,0 , sfi_parse_cpus); +#endif +#ifdef CONFIG_X86_IO_APIC +sfi_table_parse (SFI_SIG_APIC ,NULL ,NULL ,0 , sfi_parse_ioapic);
General comment: sfi_table_parse() has these pointless NULL, NULL, 0 portions 90% of the uses i've seen. They are the 'any match' key for table parsing.
Combined with the struct table_key suggestion i made in the other reply, we could have this define:
#define SFI_ANY_KEY { .signature = NULL, .oem_id = NULL, .oem_table_id = 0 }
and write those 'any match' lines as:
sfi_table_parse(SFI_SIG_CPUS, SFI_ANY_KEY, sfi_parse_cpus);
which is _far_ more readable and more extensible as well. (it is trivial to extend such a design with a new key field - while with the current open-coded structure it's far more invasive to do such a change.)
Thanks,
Ingo
Re: [PATCH 07/12] SFI: add x86 support
Quoted 37 lines · On Fri, 10 Jul 2009 14:37:26 +0800 Ingo Molnar <[email protected]> wrote:
Quoted 21 lines · Len Brown
From: Feng Tang <[email protected]>
arch/x86/kernel/sfi.cserves the dual-purpose of supporting the SFI core with arch specific code, as well as a home for the arch-specific code that uses SFI.Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/sfi.c | 284++++++++++++++++++++++++++++++++++++++++++++++
drivers/sfi/sfi_core.c| 2 +- 3 files changed, 286
insertions(+), 1 deletions(-) create mode 100644arch/x86/kernel/sfi.carch/x86/kernel/Makefile +0
-0arch/x86/kernel/Makefile obj-y += step.o · line 59
Quoted 7 lines
arch/x86/kernel/Makefile +1
-0@@ -53,6 +53,7 @@ obj-y += step.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += cpu/ obj-y += acpi/ +obj-$(CONFIG_SFI) += sfi.o obj-y += reboot.o obj-$(CONFIG_MCA) += mca_32.o obj-$(CONFIG_X86_MSR) += msr.oand write those 'any match' lines as:
sfi_table_parse(SFI_SIG_CPUS, SFI_ANY_KEY, sfi_parse_cpus);
Quoted 8 lines
which is _far_ more readable and more extensible as well. (it is trivial to extend such a design with a new key field - while with the current open-coded structure it's far more invasive to do such a change.)
Thanks,
Ingo
Thanks again for the great comments to this v2 series, will address them soon.
Thanks,
Feng
Len Brown
reviewerPATCH 8/12 SFI, x86: hook e820() for memory map initialization
In reply to Len BrownFrom: Feng Tang <[email protected]>
--- arch/x86/kernel/e820.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
arch/x86/kernel/e820.c +5 -0
@@ -20,6 +20,7 @@#include <linux/pfn.h> #include <linux/suspend.h> #include <linux/firmware-map.h> +#include <linux/sfi.h> #include <asm/pgtable.h> #include <asm/page.h>
@@ -1437,6 +1438,10 @@ char *__init default_machine_specific_memory_setup(void) < 0) {u64 mem_size; +/* if SFI mmap table exists, use SFI to setup e820 mmap */ +if (!sfi_init_memory_map ()) +return "SFI" ; +/* compare results from other methods and take the greater */ if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
Signature · 1 line
1.6.0.6
H. Peter Anvin
reviewerRe: [PATCH 08/12] SFI, x86: hook e820() for memory map initialization
This bothers me... we keep saying that memory map initialization belongs to the boot loader, and yet we keep doing the opposite. This isn't just an arbitrary difference, either: it is pretty essential to being able to use the early range allocator safely.
-hpa
Quoted 31 lines · Len Brown
From: Feng Tang <[email protected]>
Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/kernel/e820.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)arch/x86/kernel/e820.c +5
-0@@ -20,6 +20,7 @@#include <linux/pfn.h> #include <linux/suspend.h> #include <linux/firmware-map.h> +#include <linux/sfi.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -1437,6 +1438,10 @@ char *__init default_machine_specific_memory_setup(void) < 0) {u64 mem_size; +/* if SFI mmap table exists, use SFI to setup e820 mmap */ +if (!sfi_init_memory_map ()) +return "SFI" ; +/* compare results from other methods and take the greater */ if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
Re: [PATCH 08/12] SFI, x86: hook e820() for memory map initialization
Quoted 6 lines · On Thu, 9 Jul 2009 05:37:08 +0800 "H. Peter Anvin" <[email protected]> wrote:
This bothers me... we keep saying that memory map initialization belongs to the boot loader, and yet we keep doing the opposite. This isn't just an arbitrary difference, either: it is pretty essential to being able to use the early range allocator safely.
-hpa
Hi hpa,
I understand your concern, and I've added that code into our boot loader for Moosrestown which sets up a e820 memory table in boot parameters by parsing SFI table.
The reason we still keep this piece of code is to be compatible with old version boot loaders which may not know SFI info yet. And sfi_init_memory_map() only get called when kernel can't find an e820 table in boot parameters.
Anyway, I think we can remove the code if it really breaks the rule.
Thanks,
Feng
Quoted 36 lines
Quoted 32 lines · Len Brown
From: Feng Tang <[email protected]>
Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/kernel/e820.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)arch/x86/kernel/e820.c +2
-0@@ -20,6 +20,7 @@#include <linux/pfn.h> #include <linux/suspend.h> #include <linux/firmware-map.h> +#include <linux/sfi.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -1437,6 +1438,10 @@ char *__init default_machine_specific_memory_setup(void) < 0) {u64 mem_size; +/* if SFI mmap table exists, use SFI to setup e820 mmap */
arch/x86/kernel/e820.c +3
-0+if (!sfi_init_memory_map ()) +return "SFI" ; +/* compare results from other methods and take the greater */ if (boot_params.alt_mem_k
< boot_params.screen_info.ext_mem_k) {
H. Peter Anvin
reviewerRe: [PATCH 08/12] SFI, x86: hook e820() for memory map initialization
Quoted 12 lines · Feng Tang
Hi hpa,
I understand your concern, and I've added that code into our boot loader for Moosrestown which sets up a e820 memory table in boot parameters by parsing SFI table.
The reason we still keep this piece of code is to be compatible with old version boot loaders which may not know SFI info yet. And
sfi_init_memory_map()only get called when kernel can't find an e820 table in boot parameters.
Quoted 5 lines
Anyway, I think we can remove the code if it really breaks the rule.
Thanks,
Feng
What I'm concerned about is that we will want to be able to use the range allocator, which relies on the e820 memory map, extremely early during boot. In the EFI case, we allow (*optionally*) to fill in additional information from the EFI map after initial boot, but we still require memory ranges in the initial map (they can, however, be a subset of the available memory.)
I'm really concerned about saying "well, it works now" and tying ourselves into an interface that we cannot support in the long term (read: we'll be stuck with it.)
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Len Brown
reviewerPATCH 9/12 SFI: Enable SFI to parse ACPI tables
In reply to Len BrownFrom: Feng Tang <[email protected]>
Extend SFI to access standard ACPI tables.
(eg. the PCI MCFG) using sfi_acpi_table_parse().
Note that this is _not_ a hybrid ACPI + SFI mode. The platform boots in either ACPI mode or SFI mode.
SFI runs only with acpi_disabled=1, which can be set at build-time via CONFIG_ACPI=n, or at boot time by the failure to find ACPI platform support.
So this extension simply allows SFI-platforms to re-use existing standard table formats that happen to be defined to live in ACPI envelopes.
--- drivers/sfi/Makefile | 2 + drivers/sfi/sfi_acpi.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/sfi/sfi_core.c | 2 + include/linux/sfi_acpi.h | 60 ++++++++++++++++++ 4 files changed, 215 insertions(+), 0 deletions(-) create mode 100644 drivers/sfi/sfi_acpi.c create mode 100644 include/linux/sfi_acpi.h
drivers/sfi/Makefile +2 -0
@@ -1 +1,3 @@ +obj-y += sfi_acpi.o obj-y += sfi_core.o +
drivers/sfi/sfi_acpi.c new file +151 -0
151 lines not on this page · raw message
drivers/sfi/sfi_core.c +2 -0
@@ -369,6 +369,8 @@ void __init sfi_init_late(void)/* use ioremap now after it is ready */ sfi_use_ioremap =1 ; syst_va =sfi_map_memory (syst_pa, length); + +sfi_acpi_init (); }static int __init sfi_parse_cmdline (char *arg)
include/linux/sfi_acpi.h new file +60 -0
60 lines not on this page · raw message
Signature · 1 line
1.6.0.6
Re: [PATCH 09/12] SFI: Enable SFI to parse ACPI tables
Quoted 5 lines · Len Brown
From: Feng Tang <[email protected]>
+++
b/drivers/sfi/sfi_acpi.c+static struct
acpi_table_xsdt*xsdt_va;
Should be __read_mostly.
Quoted 22 lines
drivers/sfi/sfi_acpi.c new file +22
-0+static struct acpi_table_header *sfi_acpi_get_table (char *signature, +char *oem_id,char *oem_table_id,unsigned int flags) +{ +struct acpi_table_header *th; +u32 tbl_cnt, i; +u64 pa; + + tbl_cnt =XSDT_GET_NUM_ENTRIES (xsdt_va, u64); + +for (i =0 ; i < tbl_cnt; i++) { + pa = xsdt_va->table_offset_entry[i]; + + th = (struct acpi_table_header *)sfi_map_table (pa); +if (!th) +return NULL ; + +if (strncmp (th->signature, signature,SFI_SIGNATURE_SIZE )) + goto loop_continue; + +if (oem_id &&strncmp (th->oem_id, oem_id,SFI_OEM_ID_SIZE )) + goto loop_continue; +
drivers/sfi/sfi_acpi.c line 122
Quoted 10 lines
drivers/sfi/sfi_acpi.c new file +10
-0+if (oem_table_id &&strncmp (th->oem_table_id, oem_table_id, +SFI_OEM_TABLE_ID_SIZE )) + goto loop_continue; + +return th;/* success */ +loop_continue: +sfi_unmap_table ((struct sfi_table_header *)th); + } + +return NULL ;
That loop looks weird and non-standard.
The body should be factored out into a check_table(th) helper function, and the loop can thus be written as a very straightforward one:
th = NULL;
for (i = 0; i < tbl_cnt; i++) {
pa = xsdt_va->table_offset_entry[i];
th = check_table(pa, signature, oem_id, oem_table_id))
if (IS_ERR(th))
return NULL;
if (th)
return th;
}
return th;where check_table() returns PTR_ERR(-EINVAL) on mapping failure, NULL on mismatch and a table header on match.
Also, a general comment for the whole series: the various type casts between ACPI and SFI table headers look ugly and are a bit fragile. It would be better to define explicit type conversion helper inlines between ACPI an SFI types - and those would thus be type-safe. (right now it's easy to typo a variable name and pass in something that is neither an ACPI nor an SFI header.)
So we should have two primitives:
acpi_to_sfi_table(table)
sfi_to_acpi_table(table)
drivers/sfi/sfi_acpi.c line 128
Quoted 4 lines
drivers/sfi/sfi_acpi.c new file +4
-0+static void sfi_acpi_put_table (struct acpi_table_header *table) +{ +sfi_put_table ((struct sfi_table_header *)table); +}
the above could thus be written as:
static void sfi_acpi_put_table(struct acpi_table_header *table)
{
sfi_put_table(acpi_to_sfi_table(table));
}drivers/sfi/sfi_acpi.c line 137
Quoted 8 lines
drivers/sfi/sfi_acpi.c new file +8
-0+/* +* sfi_acpi_table_parse() +* +* find specified table in XSDT, run handler on it and return its return value +*/ +int sfi_acpi_table_parse (char *signature,char *oem_id,char *oem_table_id, +unsigned int flags,int (*handler)(struct acpi_table_header *)) +{
i'd suggest to define a helper structure for the 'table key' fields above. They get passed around repetitively. Also, a acpi_handler_fn_t helper would be useful as well. That way the above prototype could be written as:
int sfi_acpi_table_parse(struct acpi_table_key key, unsigned int flags,
acpi_handler_fn_t *handler);
which is a lot more readable and 'key' could be passed straight to the sfi parser.
Quoted 3 lines
+++
b/include/linux/sfi_acpi.h+#ifdef
CONFIG_SFI
Small nit: we dont generally put tabs into ifdefs, unless strongly warranted (which this one does not seem to be).
Ingo
Len Brown
reviewerPATCH 10/12 ACPI: check acpi_disabled in acpi_table_parse()
In reply to Len BrownFrom: Len Brown <[email protected]>
Allow consumers of the acpi_table_parse() API to gracefully handle the acpi_disabled=1 case without checking the flag themselves.
--- drivers/acpi/tables.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/acpi/tables.c +3 -0
@@ -277,6 +277,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)struct acpi_table_header *table =NULL ;acpi_size tbl_size; +if (acpi_disabled) +return 1 ; +if (!handler)return -EINVAL ;
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 11/12 SFI, PCI: Hook MMCONFIG
In reply to Len BrownFrom: Feng Tang <[email protected]>
First check ACPI, and if that fails, ask SFI to find the MCFG.
--- arch/x86/Kconfig | 2 +- arch/x86/pci/mmconfig-shared.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-)
arch/x86/Kconfig +1 -1
@@ -1880,7 +1880,7 @@ config PCI_DIRECT config PCI_MMCONFIG def_bool y - depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) + depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY) config PCI_OLPC def_bool y
arch/x86/pci/mmconfig-shared.c +4 -1
@@ -13,6 +13,7 @@#include <linux/pci.h> #include <linux/init.h> #include <linux/acpi.h> +#include <linux/sfi_acpi.h> #include <linux/bitmap.h> #include <linux/sort.h> #include <asm/e820.h>
@@ -606,7 +607,9 @@ static void __init __pci_mmcfg_init(int early) }if (!known_bridge) -acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg); +if (acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg)) +sfi_acpi_table_parse (ACPI_SIG_MCFG ,NULL ,NULL ,0 , + pci_parse_mcfg);pci_mmcfg_reject_broken (early);
Signature · 1 line
1.6.0.6
Re: [PATCH 11/12] SFI, PCI: Hook MMCONFIG
Quoted 17 lines · Len Brown
From: Feng Tang <[email protected]>
First check ACPI, and if that fails, ask SFI to find the MCFG.
Cc Jesse Barnes <[email protected]>Signed-off-by Feng Tang <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/Kconfig | 2 +- arch/x86/pci/mmconfig-shared.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-)arch/x86/Kconfig +0
-0
arch/x86/Kconfig config PCI_DIRECT · line 1883
Quoted 5 lines
arch/x86/Kconfig +1
-1@@ -1880,7 +1880,7 @@ config PCI_DIRECT config PCI_MMCONFIG def_bool y - depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) + depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY)
Please also update the 64-bit side (there's no reason to do this on 32-bit only - even though your sample hw is probably 32-bit only) - and while at it, also unify the currently separate 32-bit and 64-bit PCI_MMCONFIG definitions.
arch/x86/Kconfig static void __init __pci_mmcfg_init(int early) · line 612
Quoted 8 lines
arch/x86/Kconfig +3
-1@@ -606,7 +607,9 @@ static void __init __pci_mmcfg_init(int early) } if (!known_bridge) - acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); + if (acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg)) + sfi_acpi_table_parse(ACPI_SIG_MCFG, NULL, NULL, 0, + pci_parse_mcfg);
Please introduce one common/generic helper:
x86_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
and do the fallback in that helper. We generally want to try ACPI first, SFI second. That helper makes it easier to add such fallback in other places as well, and will de-uglify the above code as well.
Ingo
Re: [PATCH 11/12] SFI, PCI: Hook MMCONFIG
Quoted 14 lines · On Fri, 10 Jul 2009 13:52:29 +0800 Ingo Molnar <[email protected]> wrote:
arch/x86/pci/mmconfig-shared.c static void __init __pci_mmcfg_init(int early) · line 614
Quoted 11 lines
arch/x86/pci/mmconfig-shared.c +3
-1@@ -606,7 +607,9 @@ static void __init __pci_mmcfg_init(int early) }if (!known_bridge) -acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg); +if (acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg)) +sfi_acpi_table_parse (ACPI_SIG_MCFG ,NULL ,NULL ,0 , + pci_parse_mcfg);Please introduce one common/generic helper:
Quoted 6 lines
x86_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);and do the fallback in that helper. We generally want to try ACPI first, SFI second. That helper makes it easier to add such fallback in other places as well, and will de-uglify the above code as well.
Should we have a new acpi_sfi.c or .h to contain all these helper functions? I think it is not appropriate to put it to either ACPI or SFI code.
Also, ACPI and SFI code under arch/x86/kernel have lots of similar code in cpu/io-apic parsing, we thought about extracting these sharable codes out and move them to apic.c/io_apic.c, but don't know if this will uglify current apic/ioapic code? how do you think about it?
Thanks,
Feng
Quoted 1 line
Ingo
Re: [PATCH 11/12] SFI, PCI: Hook MMCONFIG
Quoted 19 lines · Feng Tang
Quoted 16 lines · On Fri, 10 Jul 2009 13:52:29 +0800 Ingo Molnar <[email protected]> wrote:
arch/x86/pci/mmconfig-shared.c static void __init __pci_mmcfg_init(int early) · line 614
Quoted 11 lines
arch/x86/pci/mmconfig-shared.c +3
-1@@ -606,7 +607,9 @@ static void __init __pci_mmcfg_init(int early) }if (!known_bridge) -acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg); +if (acpi_table_parse (ACPI_SIG_MCFG , pci_parse_mcfg)) +sfi_acpi_table_parse (ACPI_SIG_MCFG ,NULL ,NULL ,0 , + pci_parse_mcfg);Please introduce one common/generic helper:
x86_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
Quoted 8 lines
Quoted 4 lines
and do the fallback in that helper. We generally want to try ACPI first, SFI second. That helper makes it easier to add such fallback in other places as well, and will de-uglify the above code as well.
Should we have a new
acpi_sfi.cor .h to contain all these helper functions? I think it is not appropriate to put it to either ACPI or SFI code.
They are of the same family and there's reuse in terms of table parsing code, etc. Do you have some nice name that covers both? I didnt find any good one beyond the x86_table_*() namespace.
Quoted 5 lines
Also, ACPI and SFI code under
arch/x86/kernelhave lots of similar code in cpu/io-apic parsing, we thought about extracting these sharable codes out and move them toapic.c/io_apic.c, but don't know if this will uglify current apic/ioapic code? how do you think about it?
it all depends on the patches ... and the APIC enumeration code definitely needs cleanups so if you can do it that would be welcome.
Ingo
Len Brown
reviewerPATCH 12/12 SFI: add boot-time initialization hooks
In reply to Len BrownFrom: Feng Tang <[email protected]>
There are two SFI boot-time hooks:
sfi_init() maps the SYST using early_ioremap() and validates all the tables.
sfi_init_late() re-maps SYST with ioremap(), and initializes the ACPI extension, if present.
--- arch/x86/kernel/setup.c | 3 +++ init/main.c | 2 ++ 2 files changed, 5 insertions(+), 0 deletions(-)
arch/x86/kernel/setup.c +3 -0
@@ -27,6 +27,7 @@#include <linux/screen_info.h> #include <linux/ioport.h> #include <linux/acpi.h> +#include <linux/sfi.h> #include <linux/apm_bios.h> #include <linux/initrd.h> #include <linux/bootmem.h>
@@ -977,6 +978,8 @@ void __init setup_arch(char **cmdline_p)*/ acpi_boot_init (); +sfi_init (); +#if defined(CONFIG_X86_MPPARSE ) || defined(CONFIG_X86_VISWS )/* * get boot-time SMP configuration:
init/main.c +2 -0
@@ -68,6 +68,7 @@#include <linux/async.h> #include <linux/kmemcheck.h> #include <linux/kmemtrace.h> +#include <linux/sfi.h> #include <trace/boot.h> #include <asm/io.h>
@@ -712,6 +713,7 @@ asmlinkage void __init start_kernel(void)check_bugs ();acpi_early_init ();/* before LAPIC and SMP init */ +sfi_init_late ();ftrace_init ();
Signature · 1 line
1.6.0.6
Quoted 11 lines · Len Brown
Feng Tang (10):
SFI, x86: addCONFIG_SFI
SFI: document boot param "sfi=off"
SFI: createinclude/linux/sfi.h
SFI: add core support
ACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooks
Now that commit quality is all the rage, let me point out a (trivial) detail that could be improved: patch title capitalization.
In particular for commits touching arch/x86/ we try to standardize on capitalizing the word after the 'x86: ' tag. But in the above titles the capitalization is mixed-case:
[aligned vertically for easier readability ]
Quoted 10 lines
SFI, x86: add CONFIG_SFI SFI: document boot param "sfi=off" SFI: create include/linux/sfi.h SFI: add core supportACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooks
So it would be more consistent to have:
Quoted 10 lines
SFI, x86: Add CONFIG_SFI SFI: Document boot param "sfi=off" SFI: Create include/linux/sfi.h SFI: Add core supportACPI, x86: Remove ACPI dependency on some IO-APIC routines
SFI: Add x86 support
SFI, x86: Hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: Add boot-time initialization hooks
( Capitalizing like that has the added (minor) benefit of making it
slightly easier to read these titles - the 'real' natural language sentence portion of the title begins with a capital letter. )
Thanks,
Ingo
Len Brown
reviewerQuoted 47 lines
Quoted 13 lines
Feng Tang (10):
SFI, x86: addCONFIG_SFI
SFI: document boot param "sfi=off"
SFI: createinclude/linux/sfi.h
SFI: add core support
ACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooksNow that commit quality is all the rage, let me point out a (trivial) detail that could be improved: patch title capitalization.
In particular for commits touching
arch/x86/we try to standardize on capitalizing the word after the 'x86: ' tag. But in the above titles the capitalization is mixed-case:[aligned vertically for easier readability ]
Quoted 10 lines
SFI, x86: add CONFIG_SFI SFI: document boot param "sfi=off" SFI: create include/linux/sfi.h SFI: add core supportACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooksSo it would be more consistent to have:
Quoted 10 lines
SFI, x86: Add CONFIG_SFI SFI: Document boot param "sfi=off" SFI: Create include/linux/sfi.h SFI: Add core supportACPI, x86: Remove ACPI dependency on some IO-APIC routines
SFI: Add x86 support
SFI, x86: Hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: Add boot-time initialization hooks
Quoted 3 lines
( Capitalizing like that has the added (minor) benefit of making it
slightly easier to read these titles - the 'real' natural language sentence portion of the title begins with a capital letter. )
Ingo,
While I really do appreciate your attention to detail, a little time off might be good for you:-)
cheers,
-Len
Quoted 47 lines · Len Brown
Quoted 47 lines
Quoted 13 lines
Feng Tang (10):
SFI, x86: addCONFIG_SFI
SFI: document boot param "sfi=off"
SFI: createinclude/linux/sfi.h
SFI: add core support
ACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooksNow that commit quality is all the rage, let me point out a (trivial) detail that could be improved: patch title capitalization.
In particular for commits touching
arch/x86/we try to standardize on capitalizing the word after the 'x86: ' tag. But in the above titles the capitalization is mixed-case:[aligned vertically for easier readability ]
Quoted 10 lines
SFI, x86: add CONFIG_SFI SFI: document boot param "sfi=off" SFI: create include/linux/sfi.h SFI: add core supportACPI, x86: remove ACPI dependency on some IO-APIC routines
SFI: add x86 support
SFI, x86: hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: add boot-time initialization hooksSo it would be more consistent to have:
Quoted 10 lines
SFI, x86: Add CONFIG_SFI SFI: Document boot param "sfi=off" SFI: Create include/linux/sfi.h SFI: Add core supportACPI, x86: Remove ACPI dependency on some IO-APIC routines
SFI: Add x86 support
SFI, x86: Hooke820()for memory map initialization
SFI: Enable SFI to parse ACPI tables
SFI, PCI: Hook MMCONFIG
SFI: Add boot-time initialization hooks
Quoted 7 lines
Quoted 3 lines
( Capitalizing like that has the added (minor) benefit of making it
slightly easier to read these titles - the 'real' natural language sentence portion of the title begins with a capital letter. )Ingo,
While I really do appreciate your attention to detail, a little time off might be good for you:-)
No objections on my part ;-)
Ingo