* [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms
@ 2009-08-21 21:29 Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 01/32] x86: Add platform_setup infrastructure Thomas Gleixner
` (33 more replies)
0 siblings, 34 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
The recently posted Moorestown support patches finally indicate the
arrival of the embedded nightmare to arch/x86.
Moorestown is a SoC with a x86 core and a bunch of random peripherals
glued around it. It finally gets rid of legacy hardware like PIT, 8042
et. al. but on the other hand it introduces the full embedded horror
by adding random peripheral IP cores as an replacement which are glued
onto the x86 CPU with duct tape and other nasty tricks.
The most remarkable achievement is the PIT replacement AHBT timer
which is originally an ARM AMBA based IP core and provides random
timer readout and other fancy features. It's the final prove that
Intel HW folks are unable to design a working timer. Sigh, I
eventually hoped that we see something usable in that area after a
decade of suffering. :(
Anyway. We want to support Moorestown & Co. nevertheless, but as we
have seen from the initial patches it needs to fiddle in the guts of
the x86 setup code. Most of the points where it interferes are already
covered by x86_quirks or paravirt modifications, but we cannot use
either of those to do sane multi platform support.
The following patch series refactors the setup related x86_quirks and
the setup related paravirt hooks and puts them into an extensible
platform_setup infrastructure to provide a proper base for adding the
Moorestown modifications. As a side effect it also unifies
time_32/64.c and removes some leftovers of the pre arch/x86 era.
Note, this is not a replacement for paravirt_ops. It is just replacing
the setup related paravirt stuff so it can be reused for other
platforms though I have to say that it removes a fair amount of
obscurity which was introduced by paravirt & Co.
The total result of this overhaul is:
arch/x86/include/asm/do_timer.h | 16 --
arch/x86/kernel/time_32.c | 137 -------------------------
arch/x86/kernel/time_64.c | 135 ------------------------
linux-2.6/arch/x86/include/asm/apic.h | 3
linux-2.6/arch/x86/include/asm/e820.h | 2
linux-2.6/arch/x86/include/asm/hypervisor.h | 2
linux-2.6/arch/x86/include/asm/io_apic.h | 3
linux-2.6/arch/x86/include/asm/irq.h | 3
linux-2.6/arch/x86/include/asm/mpspec.h | 40 ++++++-
linux-2.6/arch/x86/include/asm/paravirt.h | 63 -----------
linux-2.6/arch/x86/include/asm/pgtable.h | 10 -
linux-2.6/arch/x86/include/asm/pgtable_types.h | 4
linux-2.6/arch/x86/include/asm/platform.h | 130 +++++++++++++++++++++++
linux-2.6/arch/x86/include/asm/setup.h | 45 --------
linux-2.6/arch/x86/include/asm/time.h | 3
linux-2.6/arch/x86/include/asm/timer.h | 14 --
linux-2.6/arch/x86/include/asm/tsc.h | 3
linux-2.6/arch/x86/include/asm/vmware.h | 2
linux-2.6/arch/x86/kernel/Makefile | 4
linux-2.6/arch/x86/kernel/apic/apic.c | 3
linux-2.6/arch/x86/kernel/apic/io_apic.c | 11 --
linux-2.6/arch/x86/kernel/apic/numaq_32.c | 55 ++++------
linux-2.6/arch/x86/kernel/cpu/hypervisor.c | 14 +-
linux-2.6/arch/x86/kernel/cpu/vmware.c | 35 +++---
linux-2.6/arch/x86/kernel/e820.c | 19 ---
linux-2.6/arch/x86/kernel/head32.c | 11 +-
linux-2.6/arch/x86/kernel/head64.c | 3
linux-2.6/arch/x86/kernel/irqinit.c | 36 +-----
linux-2.6/arch/x86/kernel/kvmclock.c | 7 -
linux-2.6/arch/x86/kernel/mpparse.c | 75 ++++---------
linux-2.6/arch/x86/kernel/paravirt.c | 34 ------
linux-2.6/arch/x86/kernel/platform_setup.c | 73 +++++++++++++
linux-2.6/arch/x86/kernel/setup.c | 111 ++------------------
linux-2.6/arch/x86/kernel/smpboot.c | 4
linux-2.6/arch/x86/kernel/time.c | 120 +++++++++++++++++++++
linux-2.6/arch/x86/kernel/traps.c | 5
linux-2.6/arch/x86/kernel/tsc.c | 69 ++++++++++--
linux-2.6/arch/x86/kernel/visws_quirks.c | 56 +++-------
linux-2.6/arch/x86/kernel/vmi_32.c | 9 -
linux-2.6/arch/x86/kernel/vmiclock_32.c | 2
linux-2.6/arch/x86/lguest/boot.c | 9 -
linux-2.6/arch/x86/xen/enlighten.c | 23 ++--
linux-2.6/arch/x86/xen/irq.c | 5
linux-2.6/arch/x86/xen/mmu.c | 16 ++
linux-2.6/arch/x86/xen/mmu.h | 2
linux-2.6/arch/x86/xen/xen-ops.h | 2
linux-2.6/init/main.c | 2
47 files changed, 622 insertions(+), 808 deletions(-)
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 01/32] x86: Add platform_setup infrastructure
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 02/32] x86: Add probe_roms to platform_setup Thomas Gleixner
` (32 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-add-platform-setup.patch --]
[-- Type: text/plain, Size: 4061 bytes --]
The upcoming Moorestown support brings the embedded world to x86. The
setup code of x86 has already a couple of hooks which are either
x86_quirks or paravirt ops. Some of those setup hooks are pretty
convoluted like the timer setup and the tsc calibration code. But
there are other places which could do with a cleanup.
Instead of having inline functions/macros which are modified at
compile time I decided to introduce platform_setup ops which are
unconditional in the code and make it clear that they can be changed
either during compile time or in the early boot process. The function
pointers are initialized by default functions which can be noops so
that the pointer can be called unconditionally in the most cases. This
also allows us to remove 32bit/64bit, paravirt and other #ifdeffery.
paravirt guests are just a hardware platform in the setup code, so we
should treat them as such and not hide all behind multiple layers of
indirection and compile time dependencies.
It's obvious that platform_setup.timers.timer_init() is a function
pointer than late_time_init = choose_time_init() obscurity. It's also
way simpler to grep for platform_setup.timers.timer_init and find all
the places which modify that function pointer instead of analyzing
weak functions, macros and paravirt indirections.
Note. This is not a general paravirt_ops replacement. It just will
move setup related hooks which are potentially useful for other
platform setup purposes as well out of the paravirt domain.
Add the base infrastructure without any functionality.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 23 +++++++++++++++++++++++
arch/x86/include/asm/setup.h | 2 ++
arch/x86/kernel/Makefile | 2 +-
arch/x86/kernel/platform_setup.c | 17 +++++++++++++++++
4 files changed, 43 insertions(+), 1 deletion(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_X86_PLATFORM_H
+#define _ASM_X86_PLATFORM_H
+
+/**
+ * struct platform_setup_quirks - platform specific quirks
+ *
+ */
+struct platform_setup_quirks {
+};
+
+/**
+ * struct platform_setup_ops - functions for platform specific setup
+ *
+ */
+struct platform_setup_ops {
+ struct platform_setup_quirks quirks;
+};
+
+extern struct platform_setup_ops platform_setup;
+
+extern void platform_setup_noop(void);
+
+#endif
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -7,6 +7,8 @@
#ifndef __ASSEMBLY__
+#include <asm/platform.h>
+
/*
* Any setup quirks to be performed?
*/
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -32,7 +32,7 @@ GCOV_PROFILE_paravirt.o := n
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o
-obj-y += setup.o i8259.o irqinit.o
+obj-y += setup.o platform_setup.o i8259.o irqinit.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
obj-$(CONFIG_X86_32) += probe_roms_32.o
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2009 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+#include <linux/init.h>
+
+#include <asm/platform.h>
+
+void __cpuinit platform_setup_noop(void) { }
+
+/*
+ * The platform setup functions are preset with the default functions
+ * for standard PC hardware.
+ */
+struct __initdata platform_setup_ops platform_setup = {
+};
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 02/32] x86: Add probe_roms to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 01/32] x86: Add platform_setup infrastructure Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 22:23 ` Jeremy Fitzhardinge
2009-08-21 21:29 ` [RFC patch 03/32] x86: Add request_standard_resources to platform_setup Thomas Gleixner
` (31 subsequent siblings)
33 siblings, 1 reply; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-add-probe-roms-to-platform-setup.patch --]
[-- Type: text/plain, Size: 2520 bytes --]
probe_roms is only used on 32bit. Add it to the platform_setup code
and remove the #ifdefs.
Default initializer is platform_setup_noop() which is overridden in
the 32bit boot code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 10 ++++++++++
arch/x86/kernel/head32.c | 3 +++
arch/x86/kernel/platform_setup.c | 4 ++++
arch/x86/kernel/setup.c | 4 +---
4 files changed, 18 insertions(+), 3 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -9,10 +9,20 @@ struct platform_setup_quirks {
};
/**
+ * struct platform_setup_resources - platform specific resource related ops
+ * @probe_roms: probe BIOS roms
+ *
+ */
+struct platform_setup_resources {
+ void (*probe_roms)(void);
+};
+
+/**
* struct platform_setup_ops - functions for platform specific setup
*
*/
struct platform_setup_ops {
+ struct platform_setup_resources resources;
struct platform_setup_quirks quirks;
};
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head32.c
+++ linux-2.6/arch/x86/kernel/head32.c
@@ -29,6 +29,9 @@ void __init i386_start_kernel(void)
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
+ /* Initilize 32bit specific setup functions */
+ platform_setup.resources.probe_roms = probe_roms;
+
reserve_ebda_region();
/*
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -14,4 +14,8 @@ void __cpuinit platform_setup_noop(void)
* for standard PC hardware.
*/
struct __initdata platform_setup_ops platform_setup = {
+
+ .resources = {
+ .probe_roms = platform_setup_noop,
+ },
};
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -835,9 +835,7 @@ void __init setup_arch(char **cmdline_p)
*/
init_hypervisor(&boot_cpu_data);
-#ifdef CONFIG_X86_32
- probe_roms();
-#endif
+ platform_setup.resources.probe_roms();
/* after parse_early_param, so could debug it */
insert_resource(&iomem_resource, &code_resource);
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 03/32] x86: Add request_standard_resources to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 01/32] x86: Add platform_setup infrastructure Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 02/32] x86: Add probe_roms to platform_setup Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 04/32] x86: Add reserve_ebda_region " Thomas Gleixner
` (30 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-add-request-standard-resources-to-platform.patch --]
[-- Type: text/plain, Size: 4370 bytes --]
The 32bit and the 64bit code are slighty different in the reservation
of standard resources. Also the upcoming Moorestown support needs its
own version of that.
Add it to the platform_setup and initialize it with the 64bit
default. 32bit overrides it in early boot. Now moorestown can add it's
own override w/o sprinkling the code with more #ifdefs
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 3 +++
arch/x86/include/asm/setup.h | 3 +++
arch/x86/kernel/head32.c | 1 +
arch/x86/kernel/platform_setup.c | 3 ++-
arch/x86/kernel/setup.c | 28 ++++++++++++++++------------
5 files changed, 25 insertions(+), 13 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -11,10 +11,13 @@ struct platform_setup_quirks {
/**
* struct platform_setup_resources - platform specific resource related ops
* @probe_roms: probe BIOS roms
+ * @reserve_resources: reserve the standard resources for the
+ * platform
*
*/
struct platform_setup_resources {
void (*probe_roms)(void);
+ void (*reserve_resources)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -88,6 +88,9 @@ extern unsigned long saved_video_mode;
#define paravirt_post_allocator_init() do {} while (0)
#endif
+extern void reserve_standard_io_resources(void);
+extern void i386_reserve_resources(void);
+
#ifndef _SETUP
/*
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head32.c
+++ linux-2.6/arch/x86/kernel/head32.c
@@ -31,6 +31,7 @@ void __init i386_start_kernel(void)
#endif
/* Initilize 32bit specific setup functions */
platform_setup.resources.probe_roms = probe_roms;
+ platform_setup.resources.reserve_resources = i386_reserve_resources;
reserve_ebda_region();
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -5,7 +5,7 @@
*/
#include <linux/init.h>
-#include <asm/platform.h>
+#include <asm/setup.h>
void __cpuinit platform_setup_noop(void) { }
@@ -17,5 +17,6 @@ struct __initdata platform_setup_ops pla
.resources = {
.probe_roms = platform_setup_noop,
+ .reserve_resources = reserve_standard_io_resources,
},
};
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -171,13 +171,6 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
-static struct resource video_ram_resource = {
- .name = "Video RAM area",
- .start = 0xa0000,
- .end = 0xbffff,
- .flags = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
/* cpu data as detected by the assembly code in head.S */
struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
/* common cpu data for all cpus */
@@ -605,7 +598,7 @@ static struct resource standard_io_resou
.flags = IORESOURCE_BUSY | IORESOURCE_IO }
};
-static void __init reserve_standard_io_resources(void)
+void __init reserve_standard_io_resources(void)
{
int i;
@@ -1013,10 +1006,7 @@ void __init setup_arch(char **cmdline_p)
e820_reserve_resources();
e820_mark_nosave_regions(max_low_pfn);
-#ifdef CONFIG_X86_32
- request_resource(&iomem_resource, &video_ram_resource);
-#endif
- reserve_standard_io_resources();
+ platform_setup.resources.reserve_resources();
e820_setup_gap();
@@ -1102,4 +1092,18 @@ void __init x86_quirk_time_init(void)
irq0.mask = cpumask_of_cpu(0);
setup_irq(0, &irq0);
}
+
+static struct resource video_ram_resource = {
+ .name = "Video RAM area",
+ .start = 0xa0000,
+ .end = 0xbffff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+void __init i386_reserve_resources(void)
+{
+ request_resource(&iomem_resource, &video_ram_resource);
+ reserve_standard_io_resources();
+}
+
#endif /* CONFIG_X86_32 */
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 04/32] x86: Add reserve_ebda_region to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (2 preceding siblings ...)
2009-08-21 21:29 ` [RFC patch 03/32] x86: Add request_standard_resources to platform_setup Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 05/32] x86: Move memory_setup to platform Thomas Gleixner
` (29 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-add-reserve_ebda_region-to-platform-setup.patch --]
[-- Type: text/plain, Size: 3001 bytes --]
reserve_ebda_region needs to be called befor start_kernel. Moorestown
needs to override it. Make it a platform_setup function and initialize
it with the default reserve_ebda_region.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 2 ++
arch/x86/kernel/head32.c | 4 ++--
arch/x86/kernel/head64.c | 3 +--
arch/x86/kernel/platform_setup.c | 2 ++
4 files changed, 7 insertions(+), 4 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -13,11 +13,13 @@ struct platform_setup_quirks {
* @probe_roms: probe BIOS roms
* @reserve_resources: reserve the standard resources for the
* platform
+ * @reserve_ebda_region: reserve the extended bios data area
*
*/
struct platform_setup_resources {
void (*probe_roms)(void);
void (*reserve_resources)(void);
+ void (*reserve_ebda_region)(void);
};
/**
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head32.c
+++ linux-2.6/arch/x86/kernel/head32.c
@@ -11,7 +11,7 @@
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/e820.h>
-#include <asm/bios_ebda.h>
+#include <asm/page.h>
#include <asm/trampoline.h>
void __init i386_start_kernel(void)
@@ -33,7 +33,7 @@ void __init i386_start_kernel(void)
platform_setup.resources.probe_roms = probe_roms;
platform_setup.resources.reserve_resources = i386_reserve_resources;
- reserve_ebda_region();
+ platform_setup.resources.reserve_ebda_region();
/*
* At this point everything still needed from the boot loader
Index: linux-2.6/arch/x86/kernel/head64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head64.c
+++ linux-2.6/arch/x86/kernel/head64.c
@@ -23,7 +23,6 @@
#include <asm/sections.h>
#include <asm/kdebug.h>
#include <asm/e820.h>
-#include <asm/bios_ebda.h>
#include <asm/trampoline.h>
static void __init zap_identity_mappings(void)
@@ -112,7 +111,7 @@ void __init x86_64_start_reservations(ch
}
#endif
- reserve_ebda_region();
+ platform_setup.resources.reserve_ebda_region();
/*
* At this point everything still needed from the boot loader
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -5,6 +5,7 @@
*/
#include <linux/init.h>
+#include <asm/bios_ebda.h>
#include <asm/setup.h>
void __cpuinit platform_setup_noop(void) { }
@@ -18,5 +19,6 @@ struct __initdata platform_setup_ops pla
.resources = {
.probe_roms = platform_setup_noop,
.reserve_resources = reserve_standard_io_resources,
+ .reserve_ebda_region = reserve_ebda_region,
},
};
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 05/32] x86: Move memory_setup to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (3 preceding siblings ...)
2009-08-21 21:29 ` [RFC patch 04/32] x86: Add reserve_ebda_region " Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 06/32] x86: Sanitize smp_record and move it to platform_setup Thomas Gleixner
` (28 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-memory-setup-to-platform.patch --]
[-- Type: text/plain, Size: 7986 bytes --]
memory_setup is overridden by x86_quirks and by paravirts with weak
functions and quirks. Unify the whole mess and make it an
unconditional platform setup function which defaults to the standard
function and can be overridden by the early platform code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/e820.h | 2 --
arch/x86/include/asm/paravirt.h | 1 -
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/apic/numaq_32.c | 1 -
arch/x86/kernel/e820.c | 19 +------------------
arch/x86/kernel/paravirt.c | 6 ------
arch/x86/kernel/platform_setup.c | 2 ++
arch/x86/kernel/visws_quirks.c | 3 ++-
arch/x86/lguest/boot.c | 3 ++-
arch/x86/xen/enlighten.c | 3 ++-
11 files changed, 11 insertions(+), 32 deletions(-)
Index: linux-2.6/arch/x86/include/asm/e820.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/e820.h
+++ linux-2.6/arch/x86/include/asm/e820.h
@@ -126,8 +126,6 @@ extern void e820_reserve_resources(void)
extern void e820_reserve_resources_late(void);
extern void setup_memory_map(void);
extern char *default_machine_specific_memory_setup(void);
-extern char *machine_specific_memory_setup(void);
-extern char *memory_setup(void);
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -88,7 +88,6 @@ struct pv_init_ops {
/* Basic arch-specific setup */
void (*arch_setup)(void);
- char *(*memory_setup)(void);
void (*post_allocator_init)(void);
/* Print a banner to identify the environment */
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -14,12 +14,14 @@ struct platform_setup_quirks {
* @reserve_resources: reserve the standard resources for the
* platform
* @reserve_ebda_region: reserve the extended bios data area
+ * @memory_setup: platform specific memory setup
*
*/
struct platform_setup_resources {
void (*probe_roms)(void);
void (*reserve_resources)(void);
void (*reserve_ebda_region)(void);
+ char *(*memory_setup)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -22,7 +22,6 @@ struct x86_quirks {
int (*arch_pre_intr_init)(void);
int (*arch_intr_init)(void);
int (*arch_trap_init)(void);
- char * (*arch_memory_setup)(void);
int (*mach_get_smp_config)(unsigned int early);
int (*mach_find_smp_config)(unsigned int reserve);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -260,7 +260,6 @@ static struct x86_quirks numaq_x86_quirk
.arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL,
.arch_pre_intr_init = NULL,
- .arch_memory_setup = NULL,
.arch_intr_init = NULL,
.arch_trap_init = NULL,
.mach_get_smp_config = NULL,
Index: linux-2.6/arch/x86/kernel/e820.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/e820.c
+++ linux-2.6/arch/x86/kernel/e820.c
@@ -1455,28 +1455,11 @@ char *__init default_machine_specific_me
return who;
}
-char *__init __attribute__((weak)) machine_specific_memory_setup(void)
-{
- if (x86_quirks->arch_memory_setup) {
- char *who = x86_quirks->arch_memory_setup();
-
- if (who)
- return who;
- }
- return default_machine_specific_memory_setup();
-}
-
-/* Overridden in paravirt.c if CONFIG_PARAVIRT */
-char * __init __attribute__((weak)) memory_setup(void)
-{
- return machine_specific_memory_setup();
-}
-
void __init setup_memory_map(void)
{
char *who;
- who = memory_setup();
+ who = platform_setup.resources.memory_setup();
memcpy(&e820_saved, &e820, sizeof(struct e820map));
printk(KERN_INFO "BIOS-provided physical RAM map:\n");
e820_print_map(who);
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -60,11 +60,6 @@ static void __init default_banner(void)
pv_info.name);
}
-char *memory_setup(void)
-{
- return pv_init_ops.memory_setup();
-}
-
/* Simple instruction patching code. */
#define DEF_NATIVE(ops, name, code) \
extern const char start_##ops##_##name[], end_##ops##_##name[]; \
@@ -322,7 +317,6 @@ struct pv_init_ops pv_init_ops = {
.patch = native_patch,
.banner = default_banner,
.arch_setup = paravirt_nop,
- .memory_setup = machine_specific_memory_setup,
};
struct pv_time_ops pv_time_ops = {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -7,6 +7,7 @@
#include <asm/bios_ebda.h>
#include <asm/setup.h>
+#include <asm/e820.h>
void __cpuinit platform_setup_noop(void) { }
@@ -20,5 +21,6 @@ struct __initdata platform_setup_ops pla
.probe_roms = platform_setup_noop,
.reserve_resources = reserve_standard_io_resources,
.reserve_ebda_region = reserve_ebda_region,
+ .memory_setup = default_machine_specific_memory_setup,
},
};
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -239,7 +239,6 @@ static int visws_trap_init(void);
static struct x86_quirks visws_x86_quirks __initdata = {
.arch_time_init = visws_time_init,
.arch_pre_intr_init = visws_pre_intr_init,
- .arch_memory_setup = visws_memory_setup,
.arch_intr_init = NULL,
.arch_trap_init = visws_trap_init,
.mach_get_smp_config = visws_get_smp_config,
@@ -263,6 +262,8 @@ void __init visws_early_detect(void)
*/
x86_quirks = &visws_x86_quirks;
+ platform_setup.resources.memory_setup = visws_memory_setup;
+
/*
* Install reboot quirks:
*/
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c
+++ linux-2.6/arch/x86/lguest/boot.c
@@ -1270,7 +1270,6 @@ __init void lguest_init(void)
pv_irq_ops.safe_halt = lguest_safe_halt;
/* Setup operations */
- pv_init_ops.memory_setup = lguest_memory_setup;
pv_init_ops.patch = lguest_patch;
/* Intercepts of various CPU instructions */
@@ -1325,6 +1324,8 @@ __init void lguest_init(void)
pv_time_ops.time_init = lguest_time_init;
pv_time_ops.get_tsc_khz = lguest_tsc_khz;
+ platform_setup.resources.memory_setup = lguest_memory_setup;
+
/*
* Now is a good time to look at the implementations of these functions
* before returning to the rest of lguest_init().
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -841,7 +841,6 @@ static const struct pv_init_ops xen_init
.patch = xen_patch,
.banner = xen_banner,
- .memory_setup = xen_memory_setup,
.arch_setup = xen_arch_setup,
.post_allocator_init = xen_post_allocator_init,
};
@@ -986,6 +985,8 @@ asmlinkage void __init xen_start_kernel(
pv_apic_ops = xen_apic_ops;
pv_mmu_ops = xen_mmu_ops;
+ platform_setup.resources.memory_setup = xen_memory_setup;
+
xen_init_irq_ops();
xen_init_cpuid_mask();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 06/32] x86: Sanitize smp_record and move it to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (4 preceding siblings ...)
2009-08-21 21:29 ` [RFC patch 05/32] x86: Move memory_setup to platform Thomas Gleixner
@ 2009-08-21 21:29 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 07/32] x86: Move ioapic_ids_setup " Thomas Gleixner
` (27 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:29 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-and-sanitize-smp-record.patch --]
[-- Type: text/plain, Size: 4641 bytes --]
The x86 quirkification introduced an extra ugly hackery with a
variable pointer in the mpparse code. If the pointer is initialized
then it is dereferenced and the variable set to 0 or incremented.
Create a platform_setup quirk function and let the affected numaq code
hold the function. Default init is a setup noop.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 3 +++
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/apic/numaq_32.c | 19 ++++++++++++++++---
arch/x86/kernel/mpparse.c | 6 ++----
arch/x86/kernel/platform_setup.c | 5 +++++
5 files changed, 26 insertions(+), 8 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -3,9 +3,11 @@
/**
* struct platform_setup_quirks - platform specific quirks
+ * @mpc_record: platform specific mpc record accounting
*
*/
struct platform_setup_quirks {
+ void (*mpc_record)(unsigned int mode);
};
/**
@@ -36,5 +38,6 @@ struct platform_setup_ops {
extern struct platform_setup_ops platform_setup;
extern void platform_setup_noop(void);
+extern void platform_setup_uint_noop(unsigned int unused);
#endif
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -25,7 +25,6 @@ struct x86_quirks {
int (*mach_get_smp_config)(unsigned int early);
int (*mach_find_smp_config)(unsigned int reserve);
- int *mpc_record;
int (*mpc_apic_id)(struct mpc_cpu *m);
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -66,7 +66,6 @@ struct mpc_trans {
unsigned short trans_reserved;
};
-/* x86_quirks member */
static int mpc_record;
static struct mpc_trans *translation_table[MAX_MPC_ENTRY];
@@ -177,6 +176,19 @@ static void mpc_oem_pci_bus(struct mpc_b
quad_local_to_mp_bus_id[quad][local] = m->busid;
}
+/*
+ * Called from mpparse code.
+ * mode = 0: prescan
+ * mode = 1: one mpc entry scanned
+ */
+static void numaq_mpc_record(unsigned int mode)
+{
+ if (!mode)
+ mpc_record = 0;
+ else
+ mpc_record++;
+}
+
static void __init MP_translation_info(struct mpc_trans *m)
{
printk(KERN_INFO
@@ -264,7 +276,6 @@ static struct x86_quirks numaq_x86_quirk
.arch_trap_init = NULL,
.mach_get_smp_config = NULL,
.mach_find_smp_config = NULL,
- .mpc_record = &mpc_record,
.mpc_apic_id = mpc_apic_id,
.mpc_oem_bus_info = mpc_oem_bus_info,
.mpc_oem_pci_bus = mpc_oem_pci_bus,
@@ -285,8 +296,10 @@ static __init void early_check_numaq(voi
if (smp_found_config)
early_get_smp_config();
- if (found_numaq)
+ if (found_numaq) {
x86_quirks = &numaq_x86_quirks;
+ platform_setup.quirks.mpc_record = numaq_mpc_record;
+ }
}
int __init get_memcfg_numaq(void)
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -320,8 +320,7 @@ static int __init smp_read_mpc(struct mp
/*
* Now process the configuration blocks.
*/
- if (x86_quirks->mpc_record)
- *x86_quirks->mpc_record = 0;
+ platform_setup.quirks.mpc_record(0);
while (count < mpc->length) {
switch (*mpt) {
@@ -353,8 +352,7 @@ static int __init smp_read_mpc(struct mp
count = mpc->length;
break;
}
- if (x86_quirks->mpc_record)
- (*x86_quirks->mpc_record)++;
+ platform_setup.quirks.mpc_record(1);
}
#ifdef CONFIG_X86_BIGSMP
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -10,6 +10,7 @@
#include <asm/e820.h>
void __cpuinit platform_setup_noop(void) { }
+void __init platform_setup_uint_noop(unsigned int unused) { }
/*
* The platform setup functions are preset with the default functions
@@ -23,4 +24,8 @@ struct __initdata platform_setup_ops pla
.reserve_ebda_region = reserve_ebda_region,
.memory_setup = default_machine_specific_memory_setup,
},
+
+ .quirks = {
+ .mpc_record = platform_setup_uint_noop,
+ },
};
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 07/32] x86: Move ioapic_ids_setup to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (5 preceding siblings ...)
2009-08-21 21:29 ` [RFC patch 06/32] x86: Sanitize smp_record and move it to platform_setup Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 08/32] x86: Move mpc_apic_id " Thomas Gleixner
` (26 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-ioapic-ids-setup-to-quirks.patch --]
[-- Type: text/plain, Size: 6252 bytes --]
32bit and also the numaq code have special requirements on the
ioapic_id setup. Convert it to a platform_setup function and get rid
of the quirks and #ifdefs
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/io_apic.h | 3 ++-
arch/x86/include/asm/platform.h | 10 +++++++++-
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/apic/io_apic.c | 11 ++++-------
arch/x86/kernel/apic/numaq_32.c | 8 +-------
arch/x86/kernel/head32.c | 3 +++
arch/x86/kernel/platform_setup.c | 4 ++++
7 files changed, 23 insertions(+), 17 deletions(-)
Index: linux-2.6/arch/x86/include/asm/io_apic.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/io_apic.h
+++ linux-2.6/arch/x86/include/asm/io_apic.h
@@ -177,12 +177,13 @@ extern int setup_ioapic_entry(int apic,
int polarity, int vector, int pin);
extern void ioapic_write_entry(int apic, int pin,
struct IO_APIC_route_entry e);
+extern void setup_ioapic_ids_from_mpc(void);
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
+#define setup_ioapic_ids_from_mpc platform_setup_noop
static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
static inline void ioapic_insert_resources(void) { }
-
static inline void probe_nr_irqs_gsi(void) { }
#endif
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -4,13 +4,20 @@
/**
* struct platform_setup_quirks - platform specific quirks
* @mpc_record: platform specific mpc record accounting
- *
*/
struct platform_setup_quirks {
void (*mpc_record)(unsigned int mode);
};
/**
+ * struct platform_setup_mpparse - platform specific mpparse ops
+ * @setup_ioapic_ids: platform specific ioapic id override
+ */
+struct platform_setup_mpparse {
+ void (*setup_ioapic_ids)(void);
+};
+
+/**
* struct platform_setup_resources - platform specific resource related ops
* @probe_roms: probe BIOS roms
* @reserve_resources: reserve the standard resources for the
@@ -32,6 +39,7 @@ struct platform_setup_resources {
*/
struct platform_setup_ops {
struct platform_setup_resources resources;
+ struct platform_setup_mpparse mpparse;
struct platform_setup_quirks quirks;
};
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -30,7 +30,6 @@ struct x86_quirks {
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
unsigned short oemsize);
- int (*setup_ioapic_ids)(void);
};
extern void x86_quirk_intr_init(void);
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -2014,7 +2014,7 @@ void disable_IO_APIC(void)
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
*/
-static void __init setup_ioapic_ids_from_mpc(void)
+void __init setup_ioapic_ids_from_mpc(void)
{
union IO_APIC_reg_00 reg_00;
physid_mask_t phys_id_present_map;
@@ -2023,9 +2023,8 @@ static void __init setup_ioapic_ids_from
unsigned char old_id;
unsigned long flags;
- if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
+ if (acpi_ioapic)
return;
-
/*
* Don't check I/O APIC IDs for xAPIC systems. They have
* no meaning without the serial APIC bus.
@@ -3061,10 +3060,8 @@ void __init setup_IO_APIC(void)
/*
* Set up IO-APIC IRQ routing.
*/
-#ifdef CONFIG_X86_32
- if (!acpi_ioapic)
- setup_ioapic_ids_from_mpc();
-#endif
+ platform_setup.mpparse.setup_ioapic_ids();
+
sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -262,12 +262,6 @@ static void __init
}
}
-static int __init numaq_setup_ioapic_ids(void)
-{
- /* so can skip it */
- return 1;
-}
-
static struct x86_quirks numaq_x86_quirks __initdata = {
.arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL,
@@ -280,7 +274,6 @@ static struct x86_quirks numaq_x86_quirk
.mpc_oem_bus_info = mpc_oem_bus_info,
.mpc_oem_pci_bus = mpc_oem_pci_bus,
.smp_read_mpc_oem = smp_read_mpc_oem,
- .setup_ioapic_ids = numaq_setup_ioapic_ids,
};
static __init void early_check_numaq(void)
@@ -299,6 +292,7 @@ static __init void early_check_numaq(voi
if (found_numaq) {
x86_quirks = &numaq_x86_quirks;
platform_setup.quirks.mpc_record = numaq_mpc_record;
+ platform_setup.mpparse.setup_ioapic_ids = platform_setup_noop;
}
}
Index: linux-2.6/arch/x86/kernel/head32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/head32.c
+++ linux-2.6/arch/x86/kernel/head32.c
@@ -13,6 +13,8 @@
#include <asm/e820.h>
#include <asm/page.h>
#include <asm/trampoline.h>
+#include <asm/apic.h>
+#include <asm/io_apic.h>
void __init i386_start_kernel(void)
{
@@ -32,6 +34,7 @@ void __init i386_start_kernel(void)
/* Initilize 32bit specific setup functions */
platform_setup.resources.probe_roms = probe_roms;
platform_setup.resources.reserve_resources = i386_reserve_resources;
+ platform_setup.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
platform_setup.resources.reserve_ebda_region();
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -25,6 +25,10 @@ struct __initdata platform_setup_ops pla
.memory_setup = default_machine_specific_memory_setup,
},
+ .mpparse = {
+ .setup_ioapic_ids = platform_setup_noop,
+ },
+
.quirks = {
.mpc_record = platform_setup_uint_noop,
},
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 08/32] x86: Move mpc_apic_id to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (6 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 07/32] x86: Move ioapic_ids_setup " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 09/32] x86: Move smp_read_mpc_oem " Thomas Gleixner
` (25 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-mpc_apic_id-to-platform.patch --]
[-- Type: text/plain, Size: 4738 bytes --]
The mpc_apic_id setup is handled by a x86_quirk. Make it a
platform_setup function with a default implementation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/mpspec.h | 2 ++
arch/x86/include/asm/platform.h | 4 ++++
arch/x86/include/asm/setup.h | 2 --
arch/x86/kernel/apic/numaq_32.c | 2 +-
arch/x86/kernel/mpparse.c | 10 ++++++----
arch/x86/kernel/platform_setup.c | 2 ++
6 files changed, 15 insertions(+), 7 deletions(-)
Index: linux-2.6/arch/x86/include/asm/mpspec.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mpspec.h
+++ linux-2.6/arch/x86/include/asm/mpspec.h
@@ -62,10 +62,12 @@ extern void get_smp_config(void);
extern void find_smp_config(void);
extern void early_reserve_e820_mpc_new(void);
extern int enable_update_mptable;
+extern int default_mpc_apic_id(struct mpc_cpu *m);
#else
static inline void find_smp_config(void) { }
static inline void early_reserve_e820_mpc_new(void) { }
#define enable_update_mptable 0
+#define default_mpc_apic_id NULL
#endif
void __cpuinit generic_processor_info(int apicid, int version);
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -1,6 +1,8 @@
#ifndef _ASM_X86_PLATFORM_H
#define _ASM_X86_PLATFORM_H
+struct mpc_cpu;
+
/**
* struct platform_setup_quirks - platform specific quirks
* @mpc_record: platform specific mpc record accounting
@@ -12,9 +14,11 @@ struct platform_setup_quirks {
/**
* struct platform_setup_mpparse - platform specific mpparse ops
* @setup_ioapic_ids: platform specific ioapic id override
+ * @mpc_apic_id: platform specific mpc apic id assignment
*/
struct platform_setup_mpparse {
void (*setup_ioapic_ids)(void);
+ int (*mpc_apic_id)(struct mpc_cpu *m);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -12,7 +12,6 @@
/*
* Any setup quirks to be performed?
*/
-struct mpc_cpu;
struct mpc_bus;
struct mpc_oemtable;
@@ -25,7 +24,6 @@ struct x86_quirks {
int (*mach_get_smp_config)(unsigned int early);
int (*mach_find_smp_config)(unsigned int reserve);
- int (*mpc_apic_id)(struct mpc_cpu *m);
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -270,7 +270,6 @@ static struct x86_quirks numaq_x86_quirk
.arch_trap_init = NULL,
.mach_get_smp_config = NULL,
.mach_find_smp_config = NULL,
- .mpc_apic_id = mpc_apic_id,
.mpc_oem_bus_info = mpc_oem_bus_info,
.mpc_oem_pci_bus = mpc_oem_pci_bus,
.smp_read_mpc_oem = smp_read_mpc_oem,
@@ -293,6 +292,7 @@ static __init void early_check_numaq(voi
x86_quirks = &numaq_x86_quirks;
platform_setup.quirks.mpc_record = numaq_mpc_record;
platform_setup.mpparse.setup_ioapic_ids = platform_setup_noop;
+ platform_setup.mpparse.mpc_apic_id = mpc_apic_id;
}
}
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -45,6 +45,11 @@ static int __init mpf_checksum(unsigned
return sum & 0xFF;
}
+int __init default_mpc_apic_id(struct mpc_cpu *m)
+{
+ return m->apicid;
+}
+
static void __init MP_processor_info(struct mpc_cpu *m)
{
int apicid;
@@ -55,10 +60,7 @@ static void __init MP_processor_info(str
return;
}
- if (x86_quirks->mpc_apic_id)
- apicid = x86_quirks->mpc_apic_id(m);
- else
- apicid = m->apicid;
+ apicid = platform_setup.mpparse.mpc_apic_id(m);
if (m->cpuflag & CPU_BOOTPROCESSOR) {
bootup_cpu = " (Bootup-CPU)";
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -6,6 +6,7 @@
#include <linux/init.h>
#include <asm/bios_ebda.h>
+#include <asm/mpspec.h>
#include <asm/setup.h>
#include <asm/e820.h>
@@ -27,6 +28,7 @@ struct __initdata platform_setup_ops pla
.mpparse = {
.setup_ioapic_ids = platform_setup_noop,
+ .mpc_apic_id = default_mpc_apic_id,
},
.quirks = {
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 09/32] x86: Move smp_read_mpc_oem to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (7 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 08/32] x86: Move mpc_apic_id " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 10/32] x86: Move mpc_oem_pci_bus " Thomas Gleixner
` (24 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-smp_read_mpc_oem-to-platform.patch --]
[-- Type: text/plain, Size: 5184 bytes --]
Move smp_read_mpc_oem from quirks to platform_setup.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/mpspec.h | 2 ++
arch/x86/include/asm/platform.h | 3 +++
arch/x86/include/asm/setup.h | 3 ---
arch/x86/kernel/apic/numaq_32.c | 6 +++---
arch/x86/kernel/mpparse.c | 8 ++++----
arch/x86/kernel/platform_setup.c | 1 +
6 files changed, 13 insertions(+), 10 deletions(-)
Index: linux-2.6/arch/x86/include/asm/mpspec.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mpspec.h
+++ linux-2.6/arch/x86/include/asm/mpspec.h
@@ -63,11 +63,13 @@ extern void find_smp_config(void);
extern void early_reserve_e820_mpc_new(void);
extern int enable_update_mptable;
extern int default_mpc_apic_id(struct mpc_cpu *m);
+extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
#else
static inline void find_smp_config(void) { }
static inline void early_reserve_e820_mpc_new(void) { }
#define enable_update_mptable 0
#define default_mpc_apic_id NULL
+#define default_smp_read_mpc_oem NULL
#endif
void __cpuinit generic_processor_info(int apicid, int version);
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -2,6 +2,7 @@
#define _ASM_X86_PLATFORM_H
struct mpc_cpu;
+struct mpc_table;
/**
* struct platform_setup_quirks - platform specific quirks
@@ -15,10 +16,12 @@ struct platform_setup_quirks {
* struct platform_setup_mpparse - platform specific mpparse ops
* @setup_ioapic_ids: platform specific ioapic id override
* @mpc_apic_id: platform specific mpc apic id assignment
+ * @smp_read_mpc_oem: platform specific oem mpc table setup
*/
struct platform_setup_mpparse {
void (*setup_ioapic_ids)(void);
int (*mpc_apic_id)(struct mpc_cpu *m);
+ void (*smp_read_mpc_oem)(struct mpc_table *mpc);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -13,7 +13,6 @@
* Any setup quirks to be performed?
*/
struct mpc_bus;
-struct mpc_oemtable;
struct x86_quirks {
int (*arch_pre_time_init)(void);
@@ -26,8 +25,6 @@ struct x86_quirks {
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
- void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
- unsigned short oemsize);
};
extern void x86_quirk_intr_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -218,9 +218,9 @@ static int __init mpf_checksum(unsigned
/*
* Read/parse the MPC oem tables
*/
-static void __init
- smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
+static void __init smp_read_mpc_oem(struct mpc_table *mpc)
{
+ struct mpc_oemtable *oem_table = (void *)(long)mpc->oemptr;
int count = sizeof(*oemtable); /* the header size */
unsigned char *oemptr = ((unsigned char *)oemtable) + count;
@@ -272,7 +272,6 @@ static struct x86_quirks numaq_x86_quirk
.mach_find_smp_config = NULL,
.mpc_oem_bus_info = mpc_oem_bus_info,
.mpc_oem_pci_bus = mpc_oem_pci_bus,
- .smp_read_mpc_oem = smp_read_mpc_oem,
};
static __init void early_check_numaq(void)
@@ -293,6 +292,7 @@ static __init void early_check_numaq(voi
platform_setup.quirks.mpc_record = numaq_mpc_record;
platform_setup.mpparse.setup_ioapic_ids = platform_setup_noop;
platform_setup.mpparse.mpc_apic_id = mpc_apic_id;
+ platform_setup.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
}
}
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -293,6 +293,8 @@ static void __init smp_dump_mptable(stru
1, mpc, mpc->length, 1);
}
+void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
+
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
{
char str[16];
@@ -314,10 +316,8 @@ static int __init smp_read_mpc(struct mp
if (early)
return 1;
- if (mpc->oemptr && x86_quirks->smp_read_mpc_oem) {
- struct mpc_oemtable *oem_table = (void *)(long)mpc->oemptr;
- x86_quirks->smp_read_mpc_oem(oem_table, mpc->oemsize);
- }
+ if (mpc->oemptr)
+ platform_setup.mpparse.smp_read_mpc_oem(mpc);
/*
* Now process the configuration blocks.
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -29,6 +29,7 @@ struct __initdata platform_setup_ops pla
.mpparse = {
.setup_ioapic_ids = platform_setup_noop,
.mpc_apic_id = default_mpc_apic_id,
+ .smp_read_mpc_oem = default_smp_read_mpc_oem,
},
.quirks = {
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 10/32] x86: Move mpc_oem_pci_bus to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (8 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 09/32] x86: Move smp_read_mpc_oem " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 11/32] x86: Move oem_bus_info " Thomas Gleixner
` (23 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-mpc_oem_pci_bus-to-platform.patch --]
[-- Type: text/plain, Size: 3022 bytes --]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 3 +++
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/apic/numaq_32.c | 2 +-
arch/x86/kernel/mpparse.c | 4 ++--
4 files changed, 6 insertions(+), 4 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -1,6 +1,7 @@
#ifndef _ASM_X86_PLATFORM_H
#define _ASM_X86_PLATFORM_H
+struct mpc_bus;
struct mpc_cpu;
struct mpc_table;
@@ -17,11 +18,13 @@ struct platform_setup_quirks {
* @setup_ioapic_ids: platform specific ioapic id override
* @mpc_apic_id: platform specific mpc apic id assignment
* @smp_read_mpc_oem: platform specific oem mpc table setup
+ * @mpc_oem_pci_bus: platform specific pci bus setup (default NULL)
*/
struct platform_setup_mpparse {
void (*setup_ioapic_ids)(void);
int (*mpc_apic_id)(struct mpc_cpu *m);
void (*smp_read_mpc_oem)(struct mpc_table *mpc);
+ void (*mpc_oem_pci_bus)(struct mpc_bus *m);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -24,7 +24,6 @@ struct x86_quirks {
int (*mach_find_smp_config)(unsigned int reserve);
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
- void (*mpc_oem_pci_bus)(struct mpc_bus *m);
};
extern void x86_quirk_intr_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -271,7 +271,6 @@ static struct x86_quirks numaq_x86_quirk
.mach_get_smp_config = NULL,
.mach_find_smp_config = NULL,
.mpc_oem_bus_info = mpc_oem_bus_info,
- .mpc_oem_pci_bus = mpc_oem_pci_bus,
};
static __init void early_check_numaq(void)
@@ -293,6 +292,7 @@ static __init void early_check_numaq(voi
platform_setup.mpparse.setup_ioapic_ids = platform_setup_noop;
platform_setup.mpparse.mpc_apic_id = mpc_apic_id;
platform_setup.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
+ platform_setup.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
}
}
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -98,8 +98,8 @@ static void __init MP_bus_info(struct mp
mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
#endif
} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
- if (x86_quirks->mpc_oem_pci_bus)
- x86_quirks->mpc_oem_pci_bus(m);
+ if (platform_setup.mpparse.mpc_oem_pci_bus)
+ platform_setup.mpparse.mpc_oem_pci_bus(m);
clear_bit(m->busid, mp_bus_not_pci);
#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 11/32] x86: Move oem_bus_info to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (9 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 10/32] x86: Move mpc_oem_pci_bus " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 12/32] x86: Move get/find_smp_config " Thomas Gleixner
` (22 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-oem-bus-info-to-platform.patch --]
[-- Type: text/plain, Size: 4827 bytes --]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/mpspec.h | 6 ++++++
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/setup.h | 3 ---
arch/x86/kernel/apic/numaq_32.c | 2 +-
arch/x86/kernel/mpparse.c | 14 ++++++++------
arch/x86/kernel/platform_setup.c | 1 +
6 files changed, 18 insertions(+), 10 deletions(-)
Index: linux-2.6/arch/x86/include/asm/mpspec.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mpspec.h
+++ linux-2.6/arch/x86/include/asm/mpspec.h
@@ -64,12 +64,18 @@ extern void early_reserve_e820_mpc_new(v
extern int enable_update_mptable;
extern int default_mpc_apic_id(struct mpc_cpu *m);
extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
+# ifdef CONFIG_X86_IO_APIC
+extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str);
+# else
+# define default_mpc_oem_bus_info NULL
+# endif
#else
static inline void find_smp_config(void) { }
static inline void early_reserve_e820_mpc_new(void) { }
#define enable_update_mptable 0
#define default_mpc_apic_id NULL
#define default_smp_read_mpc_oem NULL
+#define default_mpc_oem_bus_info NULL
#endif
void __cpuinit generic_processor_info(int apicid, int version);
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -19,12 +19,14 @@ struct platform_setup_quirks {
* @mpc_apic_id: platform specific mpc apic id assignment
* @smp_read_mpc_oem: platform specific oem mpc table setup
* @mpc_oem_pci_bus: platform specific pci bus setup (default NULL)
+ * @mpc_oem_bus_info: platform specific mpc bus info
*/
struct platform_setup_mpparse {
void (*setup_ioapic_ids)(void);
int (*mpc_apic_id)(struct mpc_cpu *m);
void (*smp_read_mpc_oem)(struct mpc_table *mpc);
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
+ void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -12,7 +12,6 @@
/*
* Any setup quirks to be performed?
*/
-struct mpc_bus;
struct x86_quirks {
int (*arch_pre_time_init)(void);
@@ -22,8 +21,6 @@ struct x86_quirks {
int (*arch_trap_init)(void);
int (*mach_get_smp_config)(unsigned int early);
int (*mach_find_smp_config)(unsigned int reserve);
-
- void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
};
extern void x86_quirk_intr_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -270,7 +270,6 @@ static struct x86_quirks numaq_x86_quirk
.arch_trap_init = NULL,
.mach_get_smp_config = NULL,
.mach_find_smp_config = NULL,
- .mpc_oem_bus_info = mpc_oem_bus_info,
};
static __init void early_check_numaq(void)
@@ -293,6 +292,7 @@ static __init void early_check_numaq(voi
platform_setup.mpparse.mpc_apic_id = mpc_apic_id;
platform_setup.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
platform_setup.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
+ platform_setup.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
}
}
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -72,16 +72,18 @@ static void __init MP_processor_info(str
}
#ifdef CONFIG_X86_IO_APIC
-static void __init MP_bus_info(struct mpc_bus *m)
+void __init default_mpc_oem_bus_info(struct mpc_bus *m, char *str)
{
- char str[7];
memcpy(str, m->bustype, 6);
str[6] = 0;
+ apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
+}
+
+static void __init MP_bus_info(struct mpc_bus *m)
+{
+ char str[7];
- if (x86_quirks->mpc_oem_bus_info)
- x86_quirks->mpc_oem_bus_info(m, str);
- else
- apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
+ platform_setup.mpparse.mpc_oem_bus_info(m, str);
#if MAX_MP_BUSSES < 256
if (m->busid >= MAX_MP_BUSSES) {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -30,6 +30,7 @@ struct __initdata platform_setup_ops pla
.setup_ioapic_ids = platform_setup_noop,
.mpc_apic_id = default_mpc_apic_id,
.smp_read_mpc_oem = default_smp_read_mpc_oem,
+ .mpc_oem_bus_info = default_mpc_oem_bus_info,
},
.quirks = {
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 12/32] x86: Move get/find_smp_config to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (10 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 11/32] x86: Move oem_bus_info " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 13/32] x86: Move pre_intr_init " Thomas Gleixner
` (21 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-get-find-smp-config-to-platform.patch --]
[-- Type: text/plain, Size: 9224 bytes --]
Replace the quirk machinery by a platform setup function which
defaults to the standard implementation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/mpspec.h | 30 ++++++++++++++++++++++++------
arch/x86/include/asm/platform.h | 4 ++++
arch/x86/include/asm/setup.h | 2 --
arch/x86/kernel/apic/numaq_32.c | 2 --
arch/x86/kernel/mpparse.c | 33 ++-------------------------------
arch/x86/kernel/platform_setup.c | 2 ++
arch/x86/kernel/setup.c | 2 --
arch/x86/kernel/visws_quirks.c | 14 ++++----------
8 files changed, 36 insertions(+), 53 deletions(-)
Index: linux-2.6/arch/x86/include/asm/mpspec.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mpspec.h
+++ linux-2.6/arch/x86/include/asm/mpspec.h
@@ -4,6 +4,7 @@
#include <linux/init.h>
#include <asm/mpspec_def.h>
+#include <asm/platform.h>
extern int apic_version[MAX_APICS];
extern int pic_mode;
@@ -41,9 +42,6 @@ extern int quad_local_to_mp_bus_id [NR_C
#endif /* CONFIG_X86_64 */
-extern void early_find_smp_config(void);
-extern void early_get_smp_config(void);
-
#if defined(CONFIG_MCA) || defined(CONFIG_EISA)
extern int mp_bus_id_to_type[MAX_MP_BUSSES];
#endif
@@ -56,10 +54,27 @@ extern int smp_found_config;
extern int mpc_default_type;
extern unsigned long mp_lapic_addr;
-extern void get_smp_config(void);
+static inline void get_smp_config(void)
+{
+ platform_setup.mpparse.get_smp_config(0);
+}
+
+static inline void early_get_smp_config(void)
+{
+ platform_setup.mpparse.get_smp_config(1);
+}
+
+static inline void find_smp_config(void)
+{
+ platform_setup.mpparse.find_smp_config(1);
+}
+
+static inline void early_find_smp_config(void)
+{
+ platform_setup.mpparse.find_smp_config(0);
+}
#ifdef CONFIG_X86_MPPARSE
-extern void find_smp_config(void);
extern void early_reserve_e820_mpc_new(void);
extern int enable_update_mptable;
extern int default_mpc_apic_id(struct mpc_cpu *m);
@@ -69,13 +84,16 @@ extern void default_mpc_oem_bus_info(str
# else
# define default_mpc_oem_bus_info NULL
# endif
+extern void default_find_smp_config(unsigned int reserve);
+extern void default_get_smp_config(unsigned int early);
#else
-static inline void find_smp_config(void) { }
static inline void early_reserve_e820_mpc_new(void) { }
#define enable_update_mptable 0
#define default_mpc_apic_id NULL
#define default_smp_read_mpc_oem NULL
#define default_mpc_oem_bus_info NULL
+#define default_find_smp_config platform_setup_uint_noop
+#define default_get_smp_config platform_setup_uint_noop
#endif
void __cpuinit generic_processor_info(int apicid, int version);
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -20,6 +20,8 @@ struct platform_setup_quirks {
* @smp_read_mpc_oem: platform specific oem mpc table setup
* @mpc_oem_pci_bus: platform specific pci bus setup (default NULL)
* @mpc_oem_bus_info: platform specific mpc bus info
+ * @find_smp_config: find the smp configuration
+ * @get_smp_config: get the smp configuration
*/
struct platform_setup_mpparse {
void (*setup_ioapic_ids)(void);
@@ -27,6 +29,8 @@ struct platform_setup_mpparse {
void (*smp_read_mpc_oem)(struct mpc_table *mpc);
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
+ void (*find_smp_config)(unsigned int reserve);
+ void (*get_smp_config)(unsigned int early);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -19,8 +19,6 @@ struct x86_quirks {
int (*arch_pre_intr_init)(void);
int (*arch_intr_init)(void);
int (*arch_trap_init)(void);
- int (*mach_get_smp_config)(unsigned int early);
- int (*mach_find_smp_config)(unsigned int reserve);
};
extern void x86_quirk_intr_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -268,8 +268,6 @@ static struct x86_quirks numaq_x86_quirk
.arch_pre_intr_init = NULL,
.arch_intr_init = NULL,
.arch_trap_init = NULL,
- .mach_get_smp_config = NULL,
- .mach_find_smp_config = NULL,
};
static __init void early_check_numaq(void)
Index: linux-2.6/arch/x86/kernel/mpparse.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/mpparse.c
+++ linux-2.6/arch/x86/kernel/mpparse.c
@@ -610,7 +610,7 @@ static int __init check_physptr(struct m
/*
* Scan the memory blocks for an SMP configuration block.
*/
-static void __init __get_smp_config(unsigned int early)
+void __init default_get_smp_config(unsigned int early)
{
struct mpf_intel *mpf = mpf_found;
@@ -627,11 +627,6 @@ static void __init __get_smp_config(unsi
if (acpi_lapic && acpi_ioapic)
return;
- if (x86_quirks->mach_get_smp_config) {
- if (x86_quirks->mach_get_smp_config(early))
- return;
- }
-
printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
mpf->specification);
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
@@ -672,16 +667,6 @@ static void __init __get_smp_config(unsi
*/
}
-void __init early_get_smp_config(void)
-{
- __get_smp_config(1);
-}
-
-void __init get_smp_config(void)
-{
- __get_smp_config(0);
-}
-
static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
{
unsigned long size = get_mpc_size(mpf->physptr);
@@ -747,14 +732,10 @@ static int __init smp_scan_config(unsign
return 0;
}
-static void __init __find_smp_config(unsigned int reserve)
+void __init default_find_smp_config(unsigned int reserve)
{
unsigned int address;
- if (x86_quirks->mach_find_smp_config) {
- if (x86_quirks->mach_find_smp_config(reserve))
- return;
- }
/*
* FIXME: Linux assumes you have 640K of base ram..
* this continues the error...
@@ -789,16 +770,6 @@ static void __init __find_smp_config(uns
smp_scan_config(address, 0x400, reserve);
}
-void __init early_find_smp_config(void)
-{
- __find_smp_config(0);
-}
-
-void __init find_smp_config(void)
-{
- __find_smp_config(1);
-}
-
#ifdef CONFIG_X86_IO_APIC
static u8 __initdata irq_used[MAX_IRQ_SOURCES];
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -31,6 +31,8 @@ struct __initdata platform_setup_ops pla
.mpc_apic_id = default_mpc_apic_id,
.smp_read_mpc_oem = default_smp_read_mpc_oem,
.mpc_oem_bus_info = default_mpc_oem_bus_info,
+ .find_smp_config = default_find_smp_config,
+ .get_smp_config = default_get_smp_config,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -981,13 +981,11 @@ void __init setup_arch(char **cmdline_p)
*/
acpi_boot_init();
-#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
/*
* get boot-time SMP configuration:
*/
if (smp_found_config)
get_smp_config();
-#endif
prefill_possible_map();
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -156,12 +156,8 @@ static void visws_machine_power_off(void
outl(PIIX_SPECIAL_STOP, 0xCFC);
}
-static int __init visws_get_smp_config(unsigned int early)
+static void __init visws_get_smp_config(unsigned int early)
{
- /*
- * Prevent MP-table parsing by the generic code:
- */
- return 1;
}
/*
@@ -208,7 +204,7 @@ static void __init MP_processor_info(str
apic_version[m->apicid] = ver;
}
-static int __init visws_find_smp_config(unsigned int reserve)
+static void __init visws_find_smp_config(unsigned int reserve)
{
struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
@@ -230,8 +226,6 @@ static int __init visws_find_smp_config(
MP_processor_info(mp++);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
- return 1;
}
static int visws_trap_init(void);
@@ -241,8 +235,6 @@ static struct x86_quirks visws_x86_quirk
.arch_pre_intr_init = visws_pre_intr_init,
.arch_intr_init = NULL,
.arch_trap_init = visws_trap_init,
- .mach_get_smp_config = visws_get_smp_config,
- .mach_find_smp_config = visws_find_smp_config,
};
void __init visws_early_detect(void)
@@ -263,6 +255,8 @@ void __init visws_early_detect(void)
x86_quirks = &visws_x86_quirks;
platform_setup.resources.memory_setup = visws_memory_setup;
+ platform_setup.mpparse.get_smp_config = visws_get_smp_config;
+ platform_setup.mpparse.find_smp_config = visws_find_smp_config;
/*
* Install reboot quirks:
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 13/32] x86: Move pre_intr_init to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (11 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 12/32] x86: Move get/find_smp_config " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 14/32] x86: Move irq_init " Thomas Gleixner
` (20 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-pre-intr-init-to-platform.patch --]
[-- Type: text/plain, Size: 5885 bytes --]
Replace the quirk machinery by a platform setup function which
defaults to the standard implementation. This is also a preparatory
patch for Moorestown support which needs to replace the default
init_ISA_irqs as well.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/irq.h | 2 ++
arch/x86/include/asm/platform.h | 10 ++++++++++
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/apic/numaq_32.c | 1 -
arch/x86/kernel/irqinit.c | 24 ++----------------------
arch/x86/kernel/platform_setup.c | 5 +++++
arch/x86/kernel/visws_quirks.c | 10 +++-------
7 files changed, 22 insertions(+), 31 deletions(-)
Index: linux-2.6/arch/x86/include/asm/irq.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/irq.h
+++ linux-2.6/arch/x86/include/asm/irq.h
@@ -47,4 +47,6 @@ extern unsigned int do_IRQ(struct pt_reg
extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
extern int vector_used_by_percpu_irq(unsigned int vector);
+extern void init_ISA_irqs(void);
+
#endif /* _ASM_X86_IRQ_H */
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -50,12 +50,22 @@ struct platform_setup_resources {
};
/**
+ * struct platform_setup_irqs - platform specific interrupt setup
+ * @pre_vector_init: init code to run before interrupt vectors
+ * are set up.
+ */
+struct platform_setup_irqs {
+ void (*pre_vector_init)(void);
+};
+
+/**
* struct platform_setup_ops - functions for platform specific setup
*
*/
struct platform_setup_ops {
struct platform_setup_resources resources;
struct platform_setup_mpparse mpparse;
+ struct platform_setup_irqs irqs;
struct platform_setup_quirks quirks;
};
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -16,7 +16,6 @@
struct x86_quirks {
int (*arch_pre_time_init)(void);
int (*arch_time_init)(void);
- int (*arch_pre_intr_init)(void);
int (*arch_intr_init)(void);
int (*arch_trap_init)(void);
};
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -265,7 +265,6 @@ static void __init smp_read_mpc_oem(stru
static struct x86_quirks numaq_x86_quirks __initdata = {
.arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL,
- .arch_pre_intr_init = NULL,
.arch_intr_init = NULL,
.arch_trap_init = NULL,
};
Index: linux-2.6/arch/x86/kernel/irqinit.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/irqinit.c
+++ linux-2.6/arch/x86/kernel/irqinit.c
@@ -116,7 +116,7 @@ int vector_used_by_percpu_irq(unsigned i
return 0;
}
-static void __init init_ISA_irqs(void)
+void __init init_ISA_irqs(void)
{
int i;
@@ -213,32 +213,12 @@ static void __init apic_intr_init(void)
#endif
}
-/**
- * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
- *
- * Description:
- * Perform any necessary interrupt initialisation prior to setting up
- * the "ordinary" interrupt call gates. For legacy reasons, the ISA
- * interrupts should be initialised here if the machine emulates a PC
- * in any way.
- **/
-static void __init x86_quirk_pre_intr_init(void)
-{
-#ifdef CONFIG_X86_32
- if (x86_quirks->arch_pre_intr_init) {
- if (x86_quirks->arch_pre_intr_init())
- return;
- }
-#endif
- init_ISA_irqs();
-}
-
void __init native_init_IRQ(void)
{
int i;
/* Execute any quirks before the call gates are initialised: */
- x86_quirk_pre_intr_init();
+ platform_setup.irqs.pre_vector_init();
apic_intr_init();
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -9,6 +9,7 @@
#include <asm/mpspec.h>
#include <asm/setup.h>
#include <asm/e820.h>
+#include <asm/irq.h>
void __cpuinit platform_setup_noop(void) { }
void __init platform_setup_uint_noop(unsigned int unused) { }
@@ -35,6 +36,10 @@ struct __initdata platform_setup_ops pla
.get_smp_config = default_get_smp_config,
},
+ .irqs = {
+ .pre_vector_init = init_ISA_irqs,
+ },
+
.quirks = {
.mpc_record = platform_setup_uint_noop,
},
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -73,14 +73,10 @@ static int __init visws_time_init(void)
return 0;
}
-static int __init visws_pre_intr_init(void)
+/* Replaces the default init_ISA_irqs in the generic setup */
+static void __init visws_pre_intr_init(void)
{
init_VISWS_APIC_irqs();
-
- /*
- * We dont want ISA irqs to be set up by the generic code:
- */
- return 1;
}
/* Quirk for machine specific memory setup. */
@@ -232,7 +228,6 @@ static int visws_trap_init(void);
static struct x86_quirks visws_x86_quirks __initdata = {
.arch_time_init = visws_time_init,
- .arch_pre_intr_init = visws_pre_intr_init,
.arch_intr_init = NULL,
.arch_trap_init = visws_trap_init,
};
@@ -257,6 +252,7 @@ void __init visws_early_detect(void)
platform_setup.resources.memory_setup = visws_memory_setup;
platform_setup.mpparse.get_smp_config = visws_get_smp_config;
platform_setup.mpparse.find_smp_config = visws_find_smp_config;
+ platform_setup.irqs.pre_vector_init = visws_pre_intr_init;
/*
* Install reboot quirks:
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 14/32] x86: Move irq_init to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (12 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 13/32] x86: Move pre_intr_init " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 15/32] x86: Move traps_init " Thomas Gleixner
` (19 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-irq-init-to-platform.patch --]
[-- Type: text/plain, Size: 8018 bytes --]
irq_init is overridden by x86_quirks and by paravirts. Unify the whole
mess and make it an unconditional platform setup function which
defaults to the standard function and can be overridden by the early
platform code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/irq.h | 1 -
arch/x86/include/asm/paravirt.h | 2 --
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/setup.h | 3 ---
arch/x86/kernel/apic/numaq_32.c | 1 -
arch/x86/kernel/irqinit.c | 12 ++++--------
arch/x86/kernel/paravirt.c | 6 ------
arch/x86/kernel/platform_setup.c | 1 +
arch/x86/kernel/setup.c | 17 -----------------
arch/x86/kernel/visws_quirks.c | 1 -
arch/x86/lguest/boot.c | 2 +-
arch/x86/xen/irq.c | 5 +++--
12 files changed, 11 insertions(+), 42 deletions(-)
Index: linux-2.6/arch/x86/include/asm/irq.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/irq.h
+++ linux-2.6/arch/x86/include/asm/irq.h
@@ -37,7 +37,6 @@ extern void fixup_irqs(void);
#endif
extern void (*generic_interrupt_extension)(void);
-extern void init_IRQ(void);
extern void native_init_IRQ(void);
extern bool handle_irq(unsigned irq, struct pt_regs *regs);
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -208,8 +208,6 @@ struct pv_cpu_ops {
};
struct pv_irq_ops {
- void (*init_IRQ)(void);
-
/*
* Get/set interrupt state. save_fl and restore_fl are only
* expected to use X86_EFLAGS_IF; all other bits
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -53,9 +53,11 @@ struct platform_setup_resources {
* struct platform_setup_irqs - platform specific interrupt setup
* @pre_vector_init: init code to run before interrupt vectors
* are set up.
+ * @intr_init: interrupt init code
*/
struct platform_setup_irqs {
void (*pre_vector_init)(void);
+ void (*intr_init)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -16,12 +16,9 @@
struct x86_quirks {
int (*arch_pre_time_init)(void);
int (*arch_time_init)(void);
- int (*arch_intr_init)(void);
int (*arch_trap_init)(void);
};
-extern void x86_quirk_intr_init(void);
-
extern void x86_quirk_trap_init(void);
extern void x86_quirk_pre_time_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -265,7 +265,6 @@ static void __init smp_read_mpc_oem(stru
static struct x86_quirks numaq_x86_quirks __initdata = {
.arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL,
- .arch_intr_init = NULL,
.arch_trap_init = NULL,
};
Index: linux-2.6/arch/x86/kernel/irqinit.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/irqinit.c
+++ linux-2.6/arch/x86/kernel/irqinit.c
@@ -140,8 +140,10 @@ void __init init_ISA_irqs(void)
}
}
-/* Overridden in paravirt.c */
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
+void init_IRQ(void)
+{
+ platform_setup.irqs.intr_init();
+}
static void __init smp_intr_init(void)
{
@@ -238,12 +240,6 @@ void __init native_init_IRQ(void)
#ifdef CONFIG_X86_32
/*
- * Call quirks after call gates are initialised (usually add in
- * the architecture specific gates):
- */
- x86_quirk_intr_init();
-
- /*
* External FPU? Set up irq13 if so, for
* original braindamaged IBM FERR coupling.
*/
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -183,11 +183,6 @@ unsigned paravirt_patch_insns(void *insn
return insn_len;
}
-void init_IRQ(void)
-{
- pv_irq_ops.init_IRQ();
-}
-
static void native_flush_tlb(void)
{
__native_flush_tlb();
@@ -328,7 +323,6 @@ struct pv_time_ops pv_time_ops = {
};
struct pv_irq_ops pv_irq_ops = {
- .init_IRQ = native_init_IRQ,
.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -38,6 +38,7 @@ struct __initdata platform_setup_ops pla
.irqs = {
.pre_vector_init = init_ISA_irqs,
+ .intr_init = native_init_IRQ,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -1021,23 +1021,6 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
/**
- * x86_quirk_intr_init - post gate setup interrupt initialisation
- *
- * Description:
- * Fill in any interrupts that may have been left out by the general
- * init_IRQ() routine. interrupts having to do with the machine rather
- * than the devices on the I/O bus (like APIC interrupts in intel MP
- * systems) are started here.
- **/
-void __init x86_quirk_intr_init(void)
-{
- if (x86_quirks->arch_intr_init) {
- if (x86_quirks->arch_intr_init())
- return;
- }
-}
-
-/**
* x86_quirk_trap_init - initialise system specific traps
*
* Description:
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -228,7 +228,6 @@ static int visws_trap_init(void);
static struct x86_quirks visws_x86_quirks __initdata = {
.arch_time_init = visws_time_init,
- .arch_intr_init = NULL,
.arch_trap_init = visws_trap_init,
};
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c
+++ linux-2.6/arch/x86/lguest/boot.c
@@ -1262,7 +1262,6 @@ __init void lguest_init(void)
*/
/* Interrupt-related operations */
- pv_irq_ops.init_IRQ = lguest_init_IRQ;
pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
@@ -1325,6 +1324,7 @@ __init void lguest_init(void)
pv_time_ops.get_tsc_khz = lguest_tsc_khz;
platform_setup.resources.memory_setup = lguest_memory_setup;
+ platform_setup.irqs.intr_init = lguest_init_IRQ;
/*
* Now is a good time to look at the implementations of these functions
Index: linux-2.6/arch/x86/xen/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/irq.c
+++ linux-2.6/arch/x86/xen/irq.c
@@ -1,5 +1,7 @@
#include <linux/hardirq.h>
+#include <asm/platform.h>
+
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/vcpu.h>
@@ -112,8 +114,6 @@ static void xen_halt(void)
}
static const struct pv_irq_ops xen_irq_ops __initdata = {
- .init_IRQ = xen_init_IRQ,
-
.save_fl = PV_CALLEE_SAVE(xen_save_fl),
.restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
@@ -129,4 +129,5 @@ static const struct pv_irq_ops xen_irq_o
void __init xen_init_irq_ops()
{
pv_irq_ops = xen_irq_ops;
+ platform_setup.irqs.intr_init = xen_init_IRQ;
}
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 15/32] x86: Move traps_init to platform_setup
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (13 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 14/32] x86: Move irq_init " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function Thomas Gleixner
` (18 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-traps-init-to-platform.patch --]
[-- Type: text/plain, Size: 4856 bytes --]
Replace the quirks by a simple platform_setup function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/setup.h | 3 ---
arch/x86/kernel/apic/numaq_32.c | 1 -
arch/x86/kernel/platform_setup.c | 1 +
arch/x86/kernel/setup.c | 15 ---------------
arch/x86/kernel/traps.c | 5 ++---
arch/x86/kernel/visws_quirks.c | 8 +++-----
7 files changed, 8 insertions(+), 27 deletions(-)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -54,10 +54,12 @@ struct platform_setup_resources {
* @pre_vector_init: init code to run before interrupt vectors
* are set up.
* @intr_init: interrupt init code
+ * @trap_init: platform specific trap setup
*/
struct platform_setup_irqs {
void (*pre_vector_init)(void);
void (*intr_init)(void);
+ void (*trap_init)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -16,11 +16,8 @@
struct x86_quirks {
int (*arch_pre_time_init)(void);
int (*arch_time_init)(void);
- int (*arch_trap_init)(void);
};
-extern void x86_quirk_trap_init(void);
-
extern void x86_quirk_pre_time_init(void);
extern void x86_quirk_time_init(void);
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -265,7 +265,6 @@ static void __init smp_read_mpc_oem(stru
static struct x86_quirks numaq_x86_quirks __initdata = {
.arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL,
- .arch_trap_init = NULL,
};
static __init void early_check_numaq(void)
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -39,6 +39,7 @@ struct __initdata platform_setup_ops pla
.irqs = {
.pre_vector_init = init_ISA_irqs,
.intr_init = native_init_IRQ,
+ .trap_init = platform_setup_noop,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -1020,21 +1020,6 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
-/**
- * x86_quirk_trap_init - initialise system specific traps
- *
- * Description:
- * Called as the final act of trap_init(). Used in VISWS to initialise
- * the various board specific APIC traps.
- **/
-void __init x86_quirk_trap_init(void)
-{
- if (x86_quirks->arch_trap_init) {
- if (x86_quirks->arch_trap_init())
- return;
- }
-}
-
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
Index: linux-2.6/arch/x86/kernel/traps.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/traps.c
+++ linux-2.6/arch/x86/kernel/traps.c
@@ -59,6 +59,7 @@
#include <asm/mach_traps.h>
#ifdef CONFIG_X86_64
+#include <asm/platform.h>
#include <asm/pgalloc.h>
#include <asm/proto.h>
#else
@@ -980,7 +981,5 @@ void __init trap_init(void)
*/
cpu_init();
-#ifdef CONFIG_X86_32
- x86_quirk_trap_init();
-#endif
+ platform_setup.irqs.trap_init();
}
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -224,11 +224,10 @@ static void __init visws_find_smp_config
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
}
-static int visws_trap_init(void);
+static void visws_trap_init(void);
static struct x86_quirks visws_x86_quirks __initdata = {
.arch_time_init = visws_time_init,
- .arch_trap_init = visws_trap_init,
};
void __init visws_early_detect(void)
@@ -252,6 +251,7 @@ void __init visws_early_detect(void)
platform_setup.mpparse.get_smp_config = visws_get_smp_config;
platform_setup.mpparse.find_smp_config = visws_find_smp_config;
platform_setup.irqs.pre_vector_init = visws_pre_intr_init;
+ platform_setup.irqs.trap_init = visws_trap_init;
/*
* Install reboot quirks:
@@ -390,12 +390,10 @@ static __init void cobalt_init(void)
co_apic_read(CO_APIC_ID));
}
-static int __init visws_trap_init(void)
+static void __init visws_trap_init(void)
{
lithium_init();
cobalt_init();
-
- return 1;
}
/*
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (14 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 15/32] x86: Move traps_init " Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 22:30 ` Jeremy Fitzhardinge
2009-08-21 21:30 ` [RFC patch 17/32] x86: Move paravirt banner printout to platform Thomas Gleixner
` (17 subsequent siblings)
33 siblings, 1 reply; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-arch-setup-to-platform.patch --]
[-- Type: text/plain, Size: 4110 bytes --]
ARCH_SETUP is a horrible hack of paravirt/xen which is way nicer to
read as a platform setup function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/paravirt.h | 2 --
arch/x86/include/asm/platform.h | 9 +++++++++
arch/x86/kernel/paravirt.c | 1 -
arch/x86/kernel/platform_setup.c | 4 ++++
arch/x86/kernel/setup.c | 6 +-----
arch/x86/xen/enlighten.c | 2 +-
6 files changed, 15 insertions(+), 9 deletions(-)
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -87,7 +87,6 @@ struct pv_init_ops {
unsigned long addr, unsigned len);
/* Basic arch-specific setup */
- void (*arch_setup)(void);
void (*post_allocator_init)(void);
/* Print a banner to identify the environment */
@@ -699,7 +698,6 @@ static inline void load_sp0(struct tss_s
PVOP_VCALL2(pv_cpu_ops.load_sp0, tss, thread);
}
-#define ARCH_SETUP pv_init_ops.arch_setup();
static inline unsigned long get_wallclock(void)
{
return PVOP_CALL0(unsigned long, pv_time_ops.get_wallclock);
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -63,6 +63,14 @@ struct platform_setup_irqs {
};
/**
+ * struct platform_setup_oem - oem platform specific customizing functions
+ * @arch_setup: platform specific architecure setup
+ */
+struct platform_setup_oem {
+ void (*arch_setup)(void);
+};
+
+/**
* struct platform_setup_ops - functions for platform specific setup
*
*/
@@ -70,6 +78,7 @@ struct platform_setup_ops {
struct platform_setup_resources resources;
struct platform_setup_mpparse mpparse;
struct platform_setup_irqs irqs;
+ struct platform_setup_oem oem;
struct platform_setup_quirks quirks;
};
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -311,7 +311,6 @@ struct pv_info pv_info = {
struct pv_init_ops pv_init_ops = {
.patch = native_patch,
.banner = default_banner,
- .arch_setup = paravirt_nop,
};
struct pv_time_ops pv_time_ops = {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -42,6 +42,10 @@ struct __initdata platform_setup_ops pla
.trap_init = platform_setup_noop,
},
+ .oem = {
+ .arch_setup = platform_setup_noop,
+ },
+
.quirks = {
.mpc_record = platform_setup_uint_noop,
},
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -108,10 +108,6 @@
#include <asm/numa_64.h>
#endif
-#ifndef ARCH_SETUP
-#define ARCH_SETUP
-#endif
-
/*
* end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
* The direct mapping extends to max_pfn_mapped, so that we can directly access
@@ -750,7 +746,7 @@ void __init setup_arch(char **cmdline_p)
}
#endif
- ARCH_SETUP
+ platform_setup.oem.arch_setup();
setup_memory_map();
parse_setup_data();
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -841,7 +841,6 @@ static const struct pv_init_ops xen_init
.patch = xen_patch,
.banner = xen_banner,
- .arch_setup = xen_arch_setup,
.post_allocator_init = xen_post_allocator_init,
};
@@ -986,6 +985,7 @@ asmlinkage void __init xen_start_kernel(
pv_mmu_ops = xen_mmu_ops;
platform_setup.resources.memory_setup = xen_memory_setup;
+ platform_setup.oem.arch_setup = xen_arch_setup;
xen_init_irq_ops();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 17/32] x86: Move paravirt banner printout to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (15 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 18/32] x86: Move paravirt pagetable_setup " Thomas Gleixner
` (16 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-banner-to-platform.patch --]
[-- Type: text/plain, Size: 4131 bytes --]
Replace another obscure paravirt magic and move it to platform
setup. Such a hook is also useful for embedded and special hardware.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/paravirt.h | 6 +++++-
arch/x86/include/asm/platform.h | 2 ++
arch/x86/kernel/paravirt.c | 10 +---------
arch/x86/kernel/platform_setup.c | 1 +
arch/x86/kernel/setup.c | 1 +
arch/x86/xen/enlighten.c | 2 +-
6 files changed, 11 insertions(+), 11 deletions(-)
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -1623,6 +1623,8 @@ static inline unsigned long __raw_local_
#undef PVOP_VCALL4
#undef PVOP_CALL4
+extern void default_banner(void);
+
#else /* __ASSEMBLY__ */
#define _PVSITE(ptype, clobbers, ops, word, algn) \
@@ -1763,5 +1765,7 @@ static inline unsigned long __raw_local_
#endif /* CONFIG_X86_32 */
#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_PARAVIRT */
+#else /* CONFIG_PARAVIRT */
+# define default_banner platform_setup_noop
+#endif /* !CONFIG_PARAVIRT */
#endif /* _ASM_X86_PARAVIRT_H */
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -65,9 +65,11 @@ struct platform_setup_irqs {
/**
* struct platform_setup_oem - oem platform specific customizing functions
* @arch_setup: platform specific architecure setup
+ * @banner: print a platform specific banner
*/
struct platform_setup_oem {
void (*arch_setup)(void);
+ void (*banner)(void);
};
/**
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -54,7 +54,7 @@ u64 _paravirt_ident_64(u64 x)
return x;
}
-static void __init default_banner(void)
+void __init default_banner(void)
{
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
pv_info.name);
@@ -208,13 +208,6 @@ extern void native_irq_enable_sysexit(vo
extern void native_usergs_sysret32(void);
extern void native_usergs_sysret64(void);
-static int __init print_banner(void)
-{
- pv_init_ops.banner();
- return 0;
-}
-core_initcall(print_banner);
-
static struct resource reserve_ioports = {
.start = 0,
.end = IO_SPACE_LIMIT,
@@ -310,7 +303,6 @@ struct pv_info pv_info = {
struct pv_init_ops pv_init_ops = {
.patch = native_patch,
- .banner = default_banner,
};
struct pv_time_ops pv_time_ops = {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -44,6 +44,7 @@ struct __initdata platform_setup_ops pla
.oem = {
.arch_setup = platform_setup_noop,
+ .banner = default_banner,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -1012,6 +1012,7 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
+ platform_setup.oem.banner();
}
#ifdef CONFIG_X86_32
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -840,7 +840,6 @@ static const struct pv_info xen_info __i
static const struct pv_init_ops xen_init_ops __initdata = {
.patch = xen_patch,
- .banner = xen_banner,
.post_allocator_init = xen_post_allocator_init,
};
@@ -986,6 +985,7 @@ asmlinkage void __init xen_start_kernel(
platform_setup.resources.memory_setup = xen_memory_setup;
platform_setup.oem.arch_setup = xen_arch_setup;
+ platform_setup.oem.banner = xen_banner;
xen_init_irq_ops();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 18/32] x86: Move paravirt pagetable_setup to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (16 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 17/32] x86: Move paravirt banner printout to platform Thomas Gleixner
@ 2009-08-21 21:30 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 19/32] x86: Move xen_post_allocator_init into xen_pagetable_setup_done Thomas Gleixner
` (15 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:30 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-pagetable-setup-start-done-to-platform.patch --]
[-- Type: text/plain, Size: 8168 bytes --]
Replace more paravirt hackery by proper platform setup.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/paravirt.h | 19 -------------------
arch/x86/include/asm/pgtable.h | 10 ----------
arch/x86/include/asm/pgtable_types.h | 4 ++--
arch/x86/include/asm/platform.h | 13 +++++++++++++
arch/x86/kernel/paravirt.c | 7 -------
arch/x86/kernel/platform_setup.c | 6 ++++++
arch/x86/kernel/setup.c | 4 ++--
arch/x86/xen/enlighten.c | 2 +-
arch/x86/xen/mmu.c | 11 +++++++----
arch/x86/xen/mmu.h | 2 +-
10 files changed, 32 insertions(+), 46 deletions(-)
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -241,15 +241,6 @@ struct pv_apic_ops {
};
struct pv_mmu_ops {
- /*
- * Called before/after init_mm pagetable setup. setup_start
- * may reset %cr3, and may pre-install parts of the pagetable;
- * pagetable setup is expected to preserve any existing
- * mapping.
- */
- void (*pagetable_setup_start)(pgd_t *pgd_base);
- void (*pagetable_setup_done)(pgd_t *pgd_base);
-
unsigned long (*read_cr2)(void);
void (*write_cr2)(unsigned long);
@@ -1025,16 +1016,6 @@ static inline void paravirt_post_allocat
(*pv_init_ops.post_allocator_init)();
}
-static inline void paravirt_pagetable_setup_start(pgd_t *base)
-{
- (*pv_mmu_ops.pagetable_setup_start)(base);
-}
-
-static inline void paravirt_pagetable_setup_done(pgd_t *base)
-{
- (*pv_mmu_ops.pagetable_setup_done)(base);
-}
-
#ifdef CONFIG_SMP
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
unsigned long start_esp)
Index: linux-2.6/arch/x86/include/asm/pgtable.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/pgtable.h
+++ linux-2.6/arch/x86/include/asm/pgtable.h
@@ -55,16 +55,6 @@ extern struct list_head pgd_list;
#define pte_update(mm, addr, ptep) do { } while (0)
#define pte_update_defer(mm, addr, ptep) do { } while (0)
-static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
-{
- native_pagetable_setup_start(base);
-}
-
-static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
-{
- native_pagetable_setup_done(base);
-}
-
#define pgd_val(x) native_pgd_val(x)
#define __pgd(x) native_make_pgd(x)
Index: linux-2.6/arch/x86/include/asm/pgtable_types.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/pgtable_types.h
+++ linux-2.6/arch/x86/include/asm/pgtable_types.h
@@ -299,8 +299,8 @@ void set_pte_vaddr(unsigned long vaddr,
extern void native_pagetable_setup_start(pgd_t *base);
extern void native_pagetable_setup_done(pgd_t *base);
#else
-static inline void native_pagetable_setup_start(pgd_t *base) {}
-static inline void native_pagetable_setup_done(pgd_t *base) {}
+#define native_pagetable_setup_start platform_setup_pgd_noop
+#define native_pagetable_setup_done platform_setup_pgd_noop
#endif
struct seq_file;
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -1,6 +1,8 @@
#ifndef _ASM_X86_PLATFORM_H
#define _ASM_X86_PLATFORM_H
+#include <asm/pgtable_types.h>
+
struct mpc_bus;
struct mpc_cpu;
struct mpc_table;
@@ -73,6 +75,16 @@ struct platform_setup_oem {
};
/**
+ * struct platform_setup_paging - platform specific paging functions
+ * @pagetable_setup_start: platform specific pre paging_init() call
+ * @pagetable_setup_done: platform specific post paging_init() call
+ */
+struct platform_setup_paging {
+ void (*pagetable_setup_start)(pgd_t *base);
+ void (*pagetable_setup_done)(pgd_t *base);
+};
+
+/**
* struct platform_setup_ops - functions for platform specific setup
*
*/
@@ -81,6 +93,7 @@ struct platform_setup_ops {
struct platform_setup_mpparse mpparse;
struct platform_setup_irqs irqs;
struct platform_setup_oem oem;
+ struct platform_setup_paging paging;
struct platform_setup_quirks quirks;
};
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -402,13 +402,6 @@ struct pv_apic_ops pv_apic_ops = {
#endif
struct pv_mmu_ops pv_mmu_ops = {
-#ifndef CONFIG_X86_64
- .pagetable_setup_start = native_pagetable_setup_start,
- .pagetable_setup_done = native_pagetable_setup_done,
-#else
- .pagetable_setup_start = paravirt_nop,
- .pagetable_setup_done = paravirt_nop,
-#endif
.read_cr2 = native_read_cr2,
.write_cr2 = native_write_cr2,
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -13,6 +13,7 @@
void __cpuinit platform_setup_noop(void) { }
void __init platform_setup_uint_noop(unsigned int unused) { }
+void __init platform_setup_pgd_noop(pgd_t *unused) { }
/*
* The platform setup functions are preset with the default functions
@@ -47,6 +48,11 @@ struct __initdata platform_setup_ops pla
.banner = default_banner,
},
+ .paging = {
+ .pagetable_setup_start = native_pagetable_setup_start,
+ .pagetable_setup_done = native_pagetable_setup_done,
+ },
+
.quirks = {
.mpc_record = platform_setup_uint_noop,
},
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -959,9 +959,9 @@ void __init setup_arch(char **cmdline_p)
kvmclock_init();
#endif
- paravirt_pagetable_setup_start(swapper_pg_dir);
+ platform_setup.paging.pagetable_setup_start(swapper_pg_dir);
paging_init();
- paravirt_pagetable_setup_done(swapper_pg_dir);
+ platform_setup.paging.pagetable_setup_done(swapper_pg_dir);
paravirt_post_allocator_init();
#ifdef CONFIG_X86_64
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -981,12 +981,12 @@ asmlinkage void __init xen_start_kernel(
pv_time_ops = xen_time_ops;
pv_cpu_ops = xen_cpu_ops;
pv_apic_ops = xen_apic_ops;
- pv_mmu_ops = xen_mmu_ops;
platform_setup.resources.memory_setup = xen_memory_setup;
platform_setup.oem.arch_setup = xen_arch_setup;
platform_setup.oem.banner = xen_banner;
+ xen_init_mmu_ops();
xen_init_irq_ops();
xen_init_cpuid_mask();
Index: linux-2.6/arch/x86/xen/mmu.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/mmu.c
+++ linux-2.6/arch/x86/xen/mmu.c
@@ -1875,10 +1875,7 @@ static void xen_leave_lazy_mmu(void)
preempt_enable();
}
-const struct pv_mmu_ops xen_mmu_ops __initdata = {
- .pagetable_setup_start = xen_pagetable_setup_start,
- .pagetable_setup_done = xen_pagetable_setup_done,
-
+static const struct pv_mmu_ops xen_mmu_ops __initdata = {
.read_cr2 = xen_read_cr2,
.write_cr2 = xen_write_cr2,
@@ -1954,6 +1951,12 @@ const struct pv_mmu_ops xen_mmu_ops __in
.set_fixmap = xen_set_fixmap,
};
+void __init xen_init_mmu_ops(void)
+{
+ platform_setup.paging.pagetable_setup_start = xen_pagetable_setup_start;
+ platform_setup.paging.pagetable_setup_done = xen_pagetable_setup_done;
+ pv_mmu_ops = xen_mmu_ops;
+}
#ifdef CONFIG_XEN_DEBUG_FS
Index: linux-2.6/arch/x86/xen/mmu.h
===================================================================
--- linux-2.6.orig/arch/x86/xen/mmu.h
+++ linux-2.6/arch/x86/xen/mmu.h
@@ -59,5 +59,5 @@ void xen_ptep_modify_prot_commit(struct
unsigned long xen_read_cr2_direct(void);
-extern const struct pv_mmu_ops xen_mmu_ops;
+extern void xen_init_mmu_ops(void);
#endif /* _XEN_MMU_H */
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 19/32] x86: Move xen_post_allocator_init into xen_pagetable_setup_done
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (17 preceding siblings ...)
2009-08-21 21:30 ` [RFC patch 18/32] x86: Move paravirt pagetable_setup " Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 20/32] x86: Move percpu clockevents setup to platform Thomas Gleixner
` (14 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-post-allocator-init-to-page-table-setup-done.patch --]
[-- Type: text/plain, Size: 4064 bytes --]
We really do not need two paravirt/platform setup functions which are
called in two consecutive source lines. Move the only user of
post_allocator_init into the already existing pagetable_setup_done
function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/paravirt.h | 9 ---------
arch/x86/include/asm/setup.h | 4 ----
arch/x86/kernel/setup.c | 1 -
arch/x86/xen/enlighten.c | 2 --
arch/x86/xen/mmu.c | 5 ++++-
arch/x86/xen/xen-ops.h | 2 --
6 files changed, 4 insertions(+), 19 deletions(-)
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -86,9 +86,6 @@ struct pv_init_ops {
unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
unsigned long addr, unsigned len);
- /* Basic arch-specific setup */
- void (*post_allocator_init)(void);
-
/* Print a banner to identify the environment */
void (*banner)(void);
};
@@ -1010,12 +1007,6 @@ static inline void setup_secondary_clock
}
#endif
-static inline void paravirt_post_allocator_init(void)
-{
- if (pv_init_ops.post_allocator_init)
- (*pv_init_ops.post_allocator_init)();
-}
-
#ifdef CONFIG_SMP
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
unsigned long start_esp)
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -63,10 +63,6 @@ static inline int is_visws_box(void) { r
extern struct x86_quirks *x86_quirks;
extern unsigned long saved_video_mode;
-#ifndef CONFIG_PARAVIRT
-#define paravirt_post_allocator_init() do {} while (0)
-#endif
-
extern void reserve_standard_io_resources(void);
extern void i386_reserve_resources(void);
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -962,7 +962,6 @@ void __init setup_arch(char **cmdline_p)
platform_setup.paging.pagetable_setup_start(swapper_pg_dir);
paging_init();
platform_setup.paging.pagetable_setup_done(swapper_pg_dir);
- paravirt_post_allocator_init();
#ifdef CONFIG_X86_64
map_vsyscall();
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -839,8 +839,6 @@ static const struct pv_info xen_info __i
static const struct pv_init_ops xen_init_ops __initdata = {
.patch = xen_patch,
-
- .post_allocator_init = xen_post_allocator_init,
};
static const struct pv_time_ops xen_time_ops __initdata = {
Index: linux-2.6/arch/x86/xen/mmu.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/mmu.c
+++ linux-2.6/arch/x86/xen/mmu.c
@@ -1229,9 +1229,12 @@ static __init void xen_pagetable_setup_s
{
}
+static void xen_post_allocator_init(void);
+
static __init void xen_pagetable_setup_done(pgd_t *base)
{
xen_setup_shared_info();
+ xen_post_allocator_init();
}
static void xen_write_cr2(unsigned long cr2)
@@ -1841,7 +1844,7 @@ static void xen_set_fixmap(unsigned idx,
#endif
}
-__init void xen_post_allocator_init(void)
+static __init void xen_post_allocator_init(void)
{
pv_mmu_ops.set_pte = xen_set_pte;
pv_mmu_ops.set_pmd = xen_set_pmd;
Index: linux-2.6/arch/x86/xen/xen-ops.h
===================================================================
--- linux-2.6.orig/arch/x86/xen/xen-ops.h
+++ linux-2.6/arch/x86/xen/xen-ops.h
@@ -30,8 +30,6 @@ pgd_t *xen_setup_kernel_pagetable(pgd_t
void xen_ident_map_ISA(void);
void xen_reserve_top(void);
-void xen_post_allocator_init(void);
-
char * __init xen_memory_setup(void);
void __init xen_arch_setup(void);
void __init xen_init_IRQ(void);
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 20/32] x86: Move percpu clockevents setup to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (18 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 19/32] x86: Move xen_post_allocator_init into xen_pagetable_setup_done Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 21/32] x86: Add timer_init " Thomas Gleixner
` (13 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-platform-support-for-per-cpu-timer-setup.patch --]
[-- Type: text/plain, Size: 8452 bytes --]
paravirt overrides the setup of the default apic timers as per cpu
timers. Moorestown needs to override that as well.
Move it to platform setup and create a separate
platform_cpuhotplug_setup struct which holds the function for the
secondary evtl. hotplugabble CPUs.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/apic.h | 3 ---
arch/x86/include/asm/paravirt.h | 15 ---------------
arch/x86/include/asm/platform.h | 19 +++++++++++++++++++
arch/x86/kernel/apic/apic.c | 3 ++-
arch/x86/kernel/kvmclock.c | 5 ++++-
arch/x86/kernel/paravirt.c | 2 --
arch/x86/kernel/platform_setup.c | 9 +++++++++
arch/x86/kernel/smpboot.c | 4 ++--
arch/x86/kernel/vmi_32.c | 5 +++--
arch/x86/xen/enlighten.c | 6 ++++--
10 files changed, 43 insertions(+), 28 deletions(-)
Index: linux-2.6/arch/x86/include/asm/apic.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/apic.h
+++ linux-2.6/arch/x86/include/asm/apic.h
@@ -70,9 +70,6 @@ static inline void default_inquire_remot
*/
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
-#else
-#define setup_boot_clock setup_boot_APIC_clock
-#define setup_secondary_clock setup_secondary_APIC_clock
#endif
#ifdef CONFIG_X86_64
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -228,9 +228,6 @@ struct pv_irq_ops {
struct pv_apic_ops {
#ifdef CONFIG_X86_LOCAL_APIC
- void (*setup_boot_clock)(void);
- void (*setup_secondary_clock)(void);
-
void (*startup_ipi_hook)(int phys_apicid,
unsigned long start_eip,
unsigned long start_esp);
@@ -995,18 +992,6 @@ static inline void slow_down_io(void)
#endif
}
-#ifdef CONFIG_X86_LOCAL_APIC
-static inline void setup_boot_clock(void)
-{
- PVOP_VCALL0(pv_apic_ops.setup_boot_clock);
-}
-
-static inline void setup_secondary_clock(void)
-{
- PVOP_VCALL0(pv_apic_ops.setup_secondary_clock);
-}
-#endif
-
#ifdef CONFIG_SMP
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
unsigned long start_esp)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -85,6 +85,15 @@ struct platform_setup_paging {
};
/**
+ * struct platform_setup_timers - platform specific timer setup
+ * @setup_perpcu_clockev: set up the per cpu clock event device for the
+ * boot cpu
+ */
+struct platform_setup_timers {
+ void (*setup_percpu_clockev)(void);
+};
+
+/**
* struct platform_setup_ops - functions for platform specific setup
*
*/
@@ -94,10 +103,20 @@ struct platform_setup_ops {
struct platform_setup_irqs irqs;
struct platform_setup_oem oem;
struct platform_setup_paging paging;
+ struct platform_setup_timers timers;
struct platform_setup_quirks quirks;
};
+/**
+ * struct platform_setup_cpuhotplug - platform specific cpu hotplug setups
+ * @setup_percpu_clockev: set up the per cpu clock event device
+ */
+struct platform_setup_cpuhotplug {
+ void (*setup_percpu_clockev)(void);
+};
+
extern struct platform_setup_ops platform_setup;
+extern struct platform_setup_cpuhotplug platform_cpuhotplug_setup;
extern void platform_setup_noop(void);
extern void platform_setup_uint_noop(unsigned int unused);
Index: linux-2.6/arch/x86/kernel/apic/apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/apic.c
+++ linux-2.6/arch/x86/kernel/apic/apic.c
@@ -36,6 +36,7 @@
#include <linux/mm.h>
#include <asm/perf_counter.h>
+#include <asm/platform.h>
#include <asm/pgalloc.h>
#include <asm/atomic.h>
#include <asm/mpspec.h>
@@ -1701,7 +1702,7 @@ int __init APIC_init_uniprocessor(void)
localise_nmi_watchdog();
#endif
- setup_boot_clock();
+ platform_setup.timers.setup_percpu_clockev();
#ifdef CONFIG_X86_64
check_nmi_watchdog();
#endif
Index: linux-2.6/arch/x86/kernel/kvmclock.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/kvmclock.c
+++ linux-2.6/arch/x86/kernel/kvmclock.c
@@ -22,6 +22,8 @@
#include <asm/msr.h>
#include <asm/apic.h>
#include <linux/percpu.h>
+
+#include <asm/platform.h>
#include <asm/reboot.h>
#define KVM_SCALE 22
@@ -187,7 +189,8 @@ void __init kvmclock_init(void)
pv_time_ops.sched_clock = kvm_clock_read;
pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
#ifdef CONFIG_X86_LOCAL_APIC
- pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
+ platform_cpuhotplug_setup.setup_percpu_clockev =
+ kvm_setup_secondary_clock;
#endif
#ifdef CONFIG_SMP
smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -387,8 +387,6 @@ struct pv_cpu_ops pv_cpu_ops = {
struct pv_apic_ops pv_apic_ops = {
#ifdef CONFIG_X86_LOCAL_APIC
- .setup_boot_clock = setup_boot_APIC_clock,
- .setup_secondary_clock = setup_secondary_APIC_clock,
.startup_ipi_hook = paravirt_nop,
#endif
};
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -8,6 +8,7 @@
#include <asm/bios_ebda.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
+#include <asm/apic.h>
#include <asm/e820.h>
#include <asm/irq.h>
@@ -53,7 +54,15 @@ struct __initdata platform_setup_ops pla
.pagetable_setup_done = native_pagetable_setup_done,
},
+ .timers = {
+ .setup_percpu_clockev = setup_boot_APIC_clock,
+ },
+
.quirks = {
.mpc_record = platform_setup_uint_noop,
},
};
+
+__cpuinitdata struct platform_setup_cpuhotplug platform_cpuhotplug_setup = {
+ .setup_percpu_clockev = setup_secondary_APIC_clock,
+};
Index: linux-2.6/arch/x86/kernel/smpboot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smpboot.c
+++ linux-2.6/arch/x86/kernel/smpboot.c
@@ -323,7 +323,7 @@ notrace static void __cpuinit start_seco
/* enable local interrupts */
local_irq_enable();
- setup_secondary_clock();
+ platform_cpuhotplug_setup.setup_percpu_clockev();
wmb();
cpu_idle();
@@ -1112,7 +1112,7 @@ void __init native_smp_prepare_cpus(unsi
printk(KERN_INFO "CPU%d: ", 0);
print_cpu_info(&cpu_data(0));
- setup_boot_clock();
+ platform_setup.timers.setup_percpu_clockev();
if (is_uv_system())
uv_system_init();
Index: linux-2.6/arch/x86/kernel/vmi_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmi_32.c
+++ linux-2.6/arch/x86/kernel/vmi_32.c
@@ -821,8 +821,9 @@ static inline int __init activate_vmi(vo
pv_time_ops.get_wallclock = vmi_get_wallclock;
pv_time_ops.set_wallclock = vmi_set_wallclock;
#ifdef CONFIG_X86_LOCAL_APIC
- pv_apic_ops.setup_boot_clock = vmi_time_bsp_init;
- pv_apic_ops.setup_secondary_clock = vmi_time_ap_init;
+ platform_setup.timers.setup_percpu_clockev = vmi_time_bsp_init;
+ platform_cpuhotplug_setup.setup_percpu_clockev =
+ vmi_time_ap_init;
#endif
pv_time_ops.sched_clock = vmi_sched_clock;
pv_time_ops.get_tsc_khz = vmi_tsc_khz;
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -912,8 +912,6 @@ static const struct pv_cpu_ops xen_cpu_o
static const struct pv_apic_ops xen_apic_ops __initdata = {
#ifdef CONFIG_X86_LOCAL_APIC
- .setup_boot_clock = paravirt_nop,
- .setup_secondary_clock = paravirt_nop,
.startup_ipi_hook = paravirt_nop,
#endif
};
@@ -984,6 +982,10 @@ asmlinkage void __init xen_start_kernel(
platform_setup.oem.arch_setup = xen_arch_setup;
platform_setup.oem.banner = xen_banner;
+ /* Override the default per cpu clockevents setup functions */
+ platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
+ platform_cpuhotplug_setup.setup_percpu_clockev = platform_setup_noop;
+
xen_init_mmu_ops();
xen_init_irq_ops();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 21/32] x86: Add timer_init to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (19 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 20/32] x86: Move percpu clockevents setup to platform Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-24 6:48 ` Andrey Panin
2009-08-21 21:31 ` [RFC patch 22/32] x86: Remove do_timer hook Thomas Gleixner
` (12 subsequent siblings)
33 siblings, 1 reply; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-add-timer-init-to-platform.patch --]
[-- Type: text/plain, Size: 15887 bytes --]
The timer init code is convoluted with several quirks and the paravirt
timer chooser. Figuring out which code path is actually taken is not
for the faint hearted.
Move the numaq TSC quirk to tsc_pre_init platform function and replace
the paravirt time chooser and the remaining x86 quirk with a simple
platform setup function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/paravirt.h | 7 ------
arch/x86/include/asm/platform.h | 4 +++
arch/x86/include/asm/setup.h | 21 +------------------
arch/x86/include/asm/time.h | 1
arch/x86/include/asm/timer.h | 3 --
arch/x86/kernel/apic/numaq_32.c | 10 +--------
arch/x86/kernel/paravirt.c | 1
arch/x86/kernel/platform_setup.c | 3 ++
arch/x86/kernel/setup.c | 43 ---------------------------------------
arch/x86/kernel/time_32.c | 34 ++++++++++++++++++++----------
arch/x86/kernel/time_64.c | 9 ++++++--
arch/x86/kernel/tsc.c | 2 +
arch/x86/kernel/visws_quirks.c | 22 +++++--------------
arch/x86/kernel/vmi_32.c | 2 -
arch/x86/lguest/boot.c | 2 -
arch/x86/xen/enlighten.c | 4 +--
16 files changed, 54 insertions(+), 114 deletions(-)
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -98,8 +98,6 @@ struct pv_lazy_ops {
};
struct pv_time_ops {
- void (*time_init)(void);
-
/* Set and set time of day */
unsigned long (*get_wallclock)(void);
int (*set_wallclock)(unsigned long);
@@ -693,11 +691,6 @@ static inline int set_wallclock(unsigned
return PVOP_CALL1(int, pv_time_ops.set_wallclock, nowtime);
}
-static inline void (*choose_time_init(void))(void)
-{
- return pv_time_ops.time_init;
-}
-
/* The paravirtualized CPUID instruction. */
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -88,9 +88,13 @@ struct platform_setup_paging {
* struct platform_setup_timers - platform specific timer setup
* @setup_perpcu_clockev: set up the per cpu clock event device for the
* boot cpu
+ * @tsc_pre_init: platform function called before TSC init
+ * @timer_init: initialize the platform timer (default PIT/HPET)
*/
struct platform_setup_timers {
void (*setup_percpu_clockev)(void);
+ void (*tsc_pre_init)(void);
+ void (*timer_init)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/setup.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/setup.h
+++ linux-2.6/arch/x86/include/asm/setup.h
@@ -5,24 +5,6 @@
#define COMMAND_LINE_SIZE 2048
-#ifndef __ASSEMBLY__
-
-#include <asm/platform.h>
-
-/*
- * Any setup quirks to be performed?
- */
-
-struct x86_quirks {
- int (*arch_pre_time_init)(void);
- int (*arch_time_init)(void);
-};
-
-extern void x86_quirk_pre_time_init(void);
-extern void x86_quirk_time_init(void);
-
-#endif /* __ASSEMBLY__ */
-
#ifdef __i386__
#include <linux/pfn.h>
@@ -42,6 +24,7 @@ extern void x86_quirk_time_init(void);
#ifndef __ASSEMBLY__
#include <asm/bootparam.h>
+#include <asm/platform.h>
/* Interrupt control for vSMPowered x86_64 systems */
#ifdef CONFIG_X86_64
@@ -60,11 +43,11 @@ static inline void visws_early_detect(vo
static inline int is_visws_box(void) { return 0; }
#endif
-extern struct x86_quirks *x86_quirks;
extern unsigned long saved_video_mode;
extern void reserve_standard_io_resources(void);
extern void i386_reserve_resources(void);
+extern void setup_default_timer_irq(void);
#ifndef _SETUP
Index: linux-2.6/arch/x86/include/asm/time.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/time.h
+++ linux-2.6/arch/x86/include/asm/time.h
@@ -54,7 +54,6 @@ extern void time_init(void);
#define get_wallclock() native_get_wallclock()
#define set_wallclock(x) native_set_wallclock(x)
-#define choose_time_init() hpet_time_init
#endif /* CONFIG_PARAVIRT */
Index: linux-2.6/arch/x86/include/asm/timer.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/timer.h
+++ linux-2.6/arch/x86/include/asm/timer.h
@@ -12,8 +12,7 @@ unsigned long native_calibrate_tsc(void)
#ifdef CONFIG_X86_32
extern int timer_ack;
-extern irqreturn_t timer_interrupt(int irq, void *dev_id);
-#endif /* CONFIG_X86_32 */
+#endif
extern int recalibrate_cpu_khz(void);
extern int no_timer_check;
Index: linux-2.6/arch/x86/kernel/apic/numaq_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/numaq_32.c
+++ linux-2.6/arch/x86/kernel/apic/numaq_32.c
@@ -129,10 +129,9 @@ void __cpuinit numaq_tsc_disable(void)
}
}
-static int __init numaq_pre_time_init(void)
+static void __init numaq_tsc_init(void)
{
numaq_tsc_disable();
- return 0;
}
static inline int generate_logical_apicid(int quad, int phys_apicid)
@@ -262,11 +261,6 @@ static void __init smp_read_mpc_oem(stru
}
}
-static struct x86_quirks numaq_x86_quirks __initdata = {
- .arch_pre_time_init = numaq_pre_time_init,
- .arch_time_init = NULL,
-};
-
static __init void early_check_numaq(void)
{
/*
@@ -281,13 +275,13 @@ static __init void early_check_numaq(voi
early_get_smp_config();
if (found_numaq) {
- x86_quirks = &numaq_x86_quirks;
platform_setup.quirks.mpc_record = numaq_mpc_record;
platform_setup.mpparse.setup_ioapic_ids = platform_setup_noop;
platform_setup.mpparse.mpc_apic_id = mpc_apic_id;
platform_setup.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
platform_setup.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
platform_setup.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
+ platform_setup.tsc_pre_init = numaq_tsc_init;
}
}
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -306,7 +306,6 @@ struct pv_init_ops pv_init_ops = {
};
struct pv_time_ops pv_time_ops = {
- .time_init = hpet_time_init,
.get_wallclock = native_get_wallclock,
.set_wallclock = native_set_wallclock,
.sched_clock = native_sched_clock,
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -10,6 +10,7 @@
#include <asm/setup.h>
#include <asm/apic.h>
#include <asm/e820.h>
+#include <asm/time.h>
#include <asm/irq.h>
void __cpuinit platform_setup_noop(void) { }
@@ -56,6 +57,8 @@ struct __initdata platform_setup_ops pla
.timers = {
.setup_percpu_clockev = setup_boot_APIC_clock,
+ .tsc_pre_init = platform_setup_noop,
+ .timer_init = hpet_time_init,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -626,10 +626,6 @@ static int __init setup_elfcorehdr(char
early_param("elfcorehdr", setup_elfcorehdr);
#endif
-static struct x86_quirks default_x86_quirks __initdata;
-
-struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
-
#ifdef CONFIG_X86_RESERVE_LOW_64K
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
{
@@ -1016,45 +1012,6 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
-static struct irqaction irq0 = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
- .name = "timer"
-};
-
-/**
- * x86_quirk_pre_time_init - do any specific initialisations before.
- *
- **/
-void __init x86_quirk_pre_time_init(void)
-{
- if (x86_quirks->arch_pre_time_init)
- x86_quirks->arch_pre_time_init();
-}
-
-/**
- * x86_quirk_time_init - do any specific initialisations for the system timer.
- *
- * Description:
- * Must plug the system timer interrupt source at HZ into the IRQ listed
- * in irq_vectors.h:TIMER_IRQ
- **/
-void __init x86_quirk_time_init(void)
-{
- if (x86_quirks->arch_time_init) {
- /*
- * A nonzero return code does not mean failure, it means
- * that the architecture quirk does not want any
- * generic (timer) setup to be performed after this:
- */
- if (x86_quirks->arch_time_init())
- return;
- }
-
- irq0.mask = cpumask_of_cpu(0);
- setup_irq(0, &irq0);
-}
-
static struct resource video_ram_resource = {
.name = "Video RAM area",
.start = 0xa0000,
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(profile_pc);
* Time Stamp Counter value at the time of the timer interrupt, so that
* we later on can estimate the time of day more exactly.
*/
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
/* Keep nmi watchdog up to date */
inc_irq_stat(irq0_irqs);
@@ -113,25 +113,37 @@ irqreturn_t timer_interrupt(int irq, voi
return IRQ_HANDLED;
}
-/* Duplicate of time_init() below, with hpet_enable part added */
+static struct irqaction irq0 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+ .name = "timer"
+};
+
+void __init setup_default_timer_irq(void)
+{
+ irq0.mask = cpumask_of_cpu(0);
+ setup_irq(0, &irq0);
+}
+
+/* Default timer init function */
void __init hpet_time_init(void)
{
if (!hpet_enable())
setup_pit_timer();
- x86_quirk_time_init();
+ setup_default_timer_irq();
+}
+
+static void x86_late_time_init(void)
+{
+ platform_setup.timers.timer_init();
}
/*
- * This is called directly from init code; we must delay timer setup in the
- * HPET case as we can't make the decision to turn on HPET this early in the
- * boot process.
- *
- * The chosen time_init function will usually be hpet_time_init, above, but
- * in the case of virtual hardware, an alternative function may be substituted.
+ * Initialize TSC and delay the periodic timer init to
+ * late x86_late_time_init() so ioremap works.
*/
void __init time_init(void)
{
- x86_quirk_pre_time_init();
tsc_init();
- late_time_init = choose_time_init();
+ late_time_init = x86_late_time_init;
}
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -19,6 +19,7 @@
#include <linux/mca.h>
#include <linux/nmi.h>
+#include <asm/platform.h>
#include <asm/i8253.h>
#include <asm/hpet.h>
#include <asm/vgtod.h>
@@ -127,9 +128,13 @@ void __init hpet_time_init(void)
setup_irq(0, &irq0);
}
+static void x86_late_time_init(void)
+{
+ platform_setup.timers.timer_init();
+}
+
void __init time_init(void)
{
tsc_init();
-
- late_time_init = choose_time_init();
+ late_time_init = x86_late_time_init;
}
Index: linux-2.6/arch/x86/kernel/tsc.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/tsc.c
+++ linux-2.6/arch/x86/kernel/tsc.c
@@ -857,6 +857,8 @@ void __init tsc_init(void)
u64 lpj;
int cpu;
+ platform_setup.timers.tsc_pre_init();
+
if (!cpu_has_tsc)
return;
Index: linux-2.6/arch/x86/kernel/visws_quirks.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
+++ linux-2.6/arch/x86/kernel/visws_quirks.c
@@ -30,6 +30,7 @@
#include <asm/setup.h>
#include <asm/apic.h>
#include <asm/e820.h>
+#include <asm/time.h>
#include <asm/io.h>
#include <linux/kernel_stat.h>
@@ -53,8 +54,10 @@ int is_visws_box(void)
return visws_board_type >= 0;
}
-static int __init visws_time_init(void)
+static void __init visws_time_init(void)
{
+ hpet_time_init();
+
printk(KERN_INFO "Starting Cobalt Timer system clock\n");
/* Set the countdown value */
@@ -65,12 +68,6 @@ static int __init visws_time_init(void)
/* Enable (unmask) the timer interrupt */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
-
- /*
- * Zero return means the generic timer setup code will set up
- * the standard vector:
- */
- return 0;
}
/* Replaces the default init_ISA_irqs in the generic setup */
@@ -226,10 +223,6 @@ static void __init visws_find_smp_config
static void visws_trap_init(void);
-static struct x86_quirks visws_x86_quirks __initdata = {
- .arch_time_init = visws_time_init,
-};
-
void __init visws_early_detect(void)
{
int raw;
@@ -241,17 +234,14 @@ void __init visws_early_detect(void)
return;
/*
- * Install special quirks for timer, interrupt and memory setup:
- * Fall back to generic behavior for traps:
- * Override generic MP-table parsing:
+ * Override the default platform setup functions
*/
- x86_quirks = &visws_x86_quirks;
-
platform_setup.resources.memory_setup = visws_memory_setup;
platform_setup.mpparse.get_smp_config = visws_get_smp_config;
platform_setup.mpparse.find_smp_config = visws_find_smp_config;
platform_setup.irqs.pre_vector_init = visws_pre_intr_init;
platform_setup.irqs.trap_init = visws_trap_init;
+ platform_setup.timers.timer_init = visws_time_init;
/*
* Install reboot quirks:
Index: linux-2.6/arch/x86/kernel/vmi_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmi_32.c
+++ linux-2.6/arch/x86/kernel/vmi_32.c
@@ -817,7 +817,7 @@ static inline int __init activate_vmi(vo
vmi_timer_ops.set_alarm = vmi_get_function(VMI_CALL_SetAlarm);
vmi_timer_ops.cancel_alarm =
vmi_get_function(VMI_CALL_CancelAlarm);
- pv_time_ops.time_init = vmi_time_init;
+ platform_setup.timers.timer_init = vmi_time_init;
pv_time_ops.get_wallclock = vmi_get_wallclock;
pv_time_ops.set_wallclock = vmi_set_wallclock;
#ifdef CONFIG_X86_LOCAL_APIC
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c
+++ linux-2.6/arch/x86/lguest/boot.c
@@ -1320,11 +1320,11 @@ __init void lguest_init(void)
/* Time operations */
pv_time_ops.get_wallclock = lguest_get_wallclock;
- pv_time_ops.time_init = lguest_time_init;
pv_time_ops.get_tsc_khz = lguest_tsc_khz;
platform_setup.resources.memory_setup = lguest_memory_setup;
platform_setup.irqs.intr_init = lguest_init_IRQ;
+ platform_setup.timers.timer_init = lguest_time_init;
/*
* Now is a good time to look at the implementations of these functions
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -842,8 +842,6 @@ static const struct pv_init_ops xen_init
};
static const struct pv_time_ops xen_time_ops __initdata = {
- .time_init = xen_time_init,
-
.set_wallclock = xen_set_wallclock,
.get_wallclock = xen_get_wallclock,
.get_tsc_khz = xen_tsc_khz,
@@ -982,6 +980,8 @@ asmlinkage void __init xen_start_kernel(
platform_setup.oem.arch_setup = xen_arch_setup;
platform_setup.oem.banner = xen_banner;
+ platform_setup.timers.timer_init = xen_time_init;
+
/* Override the default per cpu clockevents setup functions */
platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
platform_cpuhotplug_setup.setup_percpu_clockev = platform_setup_noop;
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 22/32] x86: Remove do_timer hook
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (20 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 21/32] x86: Add timer_init " Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 23/32] x86: Prepare unification of time_32/64.c Thomas Gleixner
` (11 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-remove-do-timer-hook.patch --]
[-- Type: text/plain, Size: 1643 bytes --]
This is a left over of the old x86 sub arch support. Remove it and
open code it like we do in time_64.c
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/do_timer.h | 16 ----------------
arch/x86/kernel/time_32.c | 7 ++++---
2 files changed, 4 insertions(+), 19 deletions(-)
Index: linux-2.6/arch/x86/include/asm/do_timer.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/do_timer.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* defines for inline arch setup functions */
-#include <linux/clockchips.h>
-
-#include <asm/i8259.h>
-#include <asm/i8253.h>
-
-/**
- * do_timer_interrupt_hook - hook into timer tick
- *
- * Call the pit clock event handler. see asm/i8253.h
- **/
-
-static inline void do_timer_interrupt_hook(void)
-{
- global_clock_event->event_handler(global_clock_event);
-}
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -28,6 +28,7 @@
* serialize accesses to xtime/lost_ticks).
*/
+#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/time.h>
@@ -37,8 +38,8 @@
#include <asm/hpet.h>
#include <asm/time.h>
#include <asm/timer.h>
-
-#include <asm/do_timer.h>
+#include <asm/i8259.h>
+#include <asm/i8253.h>
int timer_ack;
@@ -92,7 +93,7 @@ static irqreturn_t timer_interrupt(int i
}
#endif
- do_timer_interrupt_hook();
+ global_clock_event->event_handler(global_clock_event);
#ifdef CONFIG_MCA
if (MCA_bus) {
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 23/32] x86: Prepare unification of time_32/64.c
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (21 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 22/32] x86: Remove do_timer hook Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 24/32] x86: Simplify timer_ack magic in time_32.c Thomas Gleixner
` (10 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-prepare-unification-of-time-c.patch --]
[-- Type: text/plain, Size: 3678 bytes --]
Unify the top comment and the includes.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/time_32.c | 43 ++++++++++++-------------------------------
arch/x86/kernel/time_64.c | 12 ++++--------
2 files changed, 16 insertions(+), 39 deletions(-)
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -1,45 +1,26 @@
/*
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Copyright (c) 1991,1992,1995 Linus Torvalds
+ * Copyright (c) 1994 Alan Modra
+ * Copyright (c) 1995 Markus Kuhn
+ * Copyright (c) 1996 Ingo Molnar
+ * Copyright (c) 1998 Andrea Arcangeli
+ * Copyright (c) 2002,2006 Vojtech Pavlik
+ * Copyright (c) 2003 Andi Kleen
*
- * This file contains the PC-specific time handling details:
- * reading the RTC at bootup, etc..
- * 1994-07-02 Alan Modra
- * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1995-03-26 Markus Kuhn
- * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
- * precision CMOS clock update
- * 1996-05-03 Ingo Molnar
- * fixed time warps in do_[slow|fast]_gettimeoffset()
- * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
- * "A Kernel Model for Precision Timekeeping" by Dave Mills
- * 1998-09-05 (Various)
- * More robust do_fast_gettimeoffset() algorithm implemented
- * (works with APM, Cyrix 6x86MX and Centaur C6),
- * monotonic gettimeofday() with fast_get_timeoffset(),
- * drift-proof precision TSC calibration on boot
- * (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
- * Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
- * ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
- * 1998-12-16 Andrea Arcangeli
- * Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
- * because was not accounting lost_ticks.
- * 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
- * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
- * serialize accesses to xtime/lost_ticks).
*/
#include <linux/clockchips.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/mca.h>
-#include <asm/setup.h>
-#include <asm/hpet.h>
-#include <asm/time.h>
-#include <asm/timer.h>
+#include <asm/platform.h>
#include <asm/i8259.h>
#include <asm/i8253.h>
+#include <asm/timer.h>
+#include <asm/hpet.h>
+#include <asm/time.h>
+#include <asm/nmi.h>
int timer_ack;
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -1,6 +1,4 @@
/*
- * "High Precision Event Timer" based timekeeping.
- *
* Copyright (c) 1991,1992,1995 Linus Torvalds
* Copyright (c) 1994 Alan Modra
* Copyright (c) 1995 Markus Kuhn
@@ -8,23 +6,21 @@
* Copyright (c) 1998 Andrea Arcangeli
* Copyright (c) 2002,2006 Vojtech Pavlik
* Copyright (c) 2003 Andi Kleen
- * RTC support code taken from arch/i386/kernel/timers/time_hpet.c
+ *
*/
#include <linux/clockchips.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/module.h>
#include <linux/time.h>
#include <linux/mca.h>
-#include <linux/nmi.h>
#include <asm/platform.h>
+#include <asm/i8259.h>
#include <asm/i8253.h>
+#include <asm/timer.h>
#include <asm/hpet.h>
-#include <asm/vgtod.h>
#include <asm/time.h>
-#include <asm/timer.h>
+#include <asm/nmi.h>
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 24/32] x86: Simplify timer_ack magic in time_32.c
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (22 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 23/32] x86: Prepare unification of time_32/64.c Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 25/32] x86: Remove mca bus ifdef from timer interrupt Thomas Gleixner
` (9 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-simplify-timer-ack-hack.patch --]
[-- Type: text/plain, Size: 2693 bytes --]
Let the compiler optimize the timer_ack magic away in the 32bit timer
interrupt and put the same code into time_64.c. It's optimized out for
CONFIG_X86_IO_APIC on 32bit and for 64bit because timer_ack is const 0
in both cases.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/timer.h | 6 ++++--
arch/x86/kernel/time_32.c | 5 +++--
arch/x86/kernel/time_64.c | 14 ++++++++++++++
3 files changed, 21 insertions(+), 4 deletions(-)
Index: linux-2.6/arch/x86/include/asm/timer.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/timer.h
+++ linux-2.6/arch/x86/include/asm/timer.h
@@ -9,11 +9,13 @@
unsigned long long native_sched_clock(void);
unsigned long native_calibrate_tsc(void);
+extern int recalibrate_cpu_khz(void);
-#ifdef CONFIG_X86_32
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
extern int timer_ack;
+#else
+# define timer_ack (0)
#endif
-extern int recalibrate_cpu_khz(void);
extern int no_timer_check;
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -22,7 +22,9 @@
#include <asm/time.h>
#include <asm/nmi.h>
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
int timer_ack;
+#endif
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -59,7 +61,7 @@ static irqreturn_t timer_interrupt(int i
/* Keep nmi watchdog up to date */
inc_irq_stat(irq0_irqs);
-#ifdef CONFIG_X86_IO_APIC
+ /* Optimized out for !IO_APIC and x86_64 */
if (timer_ack) {
/*
* Subtle, when I/O APICs are used we have to ack timer IRQ
@@ -72,7 +74,6 @@ static irqreturn_t timer_interrupt(int i
inb(PIC_MASTER_POLL);
spin_unlock(&i8259A_lock);
}
-#endif
global_clock_event->event_handler(global_clock_event);
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -50,6 +50,20 @@ static irqreturn_t timer_interrupt(int i
{
inc_irq_stat(irq0_irqs);
+ /* Optimized out for !IO_APIC and x86_64 */
+ if (timer_ack) {
+ /*
+ * Subtle, when I/O APICs are used we have to ack timer IRQ
+ * manually to deassert NMI lines for the watchdog if run
+ * on an 82489DX-based system.
+ */
+ spin_lock(&i8259A_lock);
+ outb(0x0c, PIC_MASTER_OCW3);
+ /* Ack the IRQ; AEOI will end it automatically. */
+ inb(PIC_MASTER_POLL);
+ spin_unlock(&i8259A_lock);
+ }
+
global_clock_event->event_handler(global_clock_event);
#ifdef CONFIG_MCA
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 25/32] x86: Remove mca bus ifdef from timer interrupt
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (23 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 24/32] x86: Simplify timer_ack magic in time_32.c Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 26/32] x86: Make timer setup and global variables the same in time_32/64.c Thomas Gleixner
` (8 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-time-remove-mca-bus-ifdef.patch --]
[-- Type: text/plain, Size: 2034 bytes --]
MCA_bus is constant 0 when CONFIG_MCA=n. So the compiler removes that
code w/o needing an extra #ifdef
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/time_32.c | 18 +++---------------
arch/x86/kernel/time_64.c | 9 +++------
2 files changed, 6 insertions(+), 21 deletions(-)
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -77,21 +77,9 @@ static irqreturn_t timer_interrupt(int i
global_clock_event->event_handler(global_clock_event);
-#ifdef CONFIG_MCA
- if (MCA_bus) {
- /* The PS/2 uses level-triggered interrupts. You can't
- turn them off, nor would you want to (any attempt to
- enable edge-triggered interrupts usually gets intercepted by a
- special hardware circuit). Hence we have to acknowledge
- the timer interrupt. Through some incredibly stupid
- design idea, the reset for IRQ 0 is done by setting the
- high bit of the PPI port B (0x61). Note that some PS/2s,
- notably the 55SX, work fine if this is removed. */
-
- u8 irq_v = inb_p(0x61); /* read the current state */
- outb_p(irq_v | 0x80, 0x61); /* reset the IRQ */
- }
-#endif
+ /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
+ if (MCA_bus)
+ outb_p(inb_p(0x61)| 0x80, 0x61);
return IRQ_HANDLED;
}
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -66,12 +66,9 @@ static irqreturn_t timer_interrupt(int i
global_clock_event->event_handler(global_clock_event);
-#ifdef CONFIG_MCA
- if (MCA_bus) {
- u8 irq_v = inb_p(0x61); /* read the current state */
- outb_p(irq_v|0x80, 0x61); /* reset the IRQ */
- }
-#endif
+ /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
+ if (MCA_bus)
+ outb_p(inb_p(0x61)| 0x80, 0x61);
return IRQ_HANDLED;
}
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 26/32] x86: Make timer setup and global variables the same in time_32/64.c
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (24 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 25/32] x86: Remove mca bus ifdef from timer interrupt Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 27/32] x86: Move calibrate_cpu to tsc.c Thomas Gleixner
` (7 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-time-unify-some-more.patch --]
[-- Type: text/plain, Size: 3465 bytes --]
The timer and timer irq setup code is identical in 32 and 64 bit. Make
it the same formatting as well. Also add the global variables under
the necessary ifdefs to both files.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/time_32.c | 8 +++++---
arch/x86/kernel/time_64.c | 38 ++++++++++++++++++++++++++++++--------
2 files changed, 35 insertions(+), 11 deletions(-)
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -26,6 +26,10 @@
int timer_ack;
#endif
+#ifdef CONFIG_X86_64
+volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+#endif
+
unsigned long profile_pc(struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
@@ -52,9 +56,7 @@ unsigned long profile_pc(struct pt_regs
EXPORT_SYMBOL(profile_pc);
/*
- * This is the same as the above, except we _also_ save the current
- * Time Stamp Counter value at the time of the timer interrupt, so that
- * we later on can estimate the time of day more exactly.
+ * Default timer interrupt handler for PIT/HPET
*/
static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -22,7 +22,13 @@
#include <asm/time.h>
#include <asm/nmi.h>
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
+int timer_ack;
+#endif
+
+#ifdef CONFIG_X86_64
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+#endif
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -46,8 +52,12 @@ unsigned long profile_pc(struct pt_regs
}
EXPORT_SYMBOL(profile_pc);
+/*
+ * Default timer interrupt handler for PIT/HPET
+ */
static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
+ /* Keep nmi watchdog up to date */
inc_irq_stat(irq0_irqs);
/* Optimized out for !IO_APIC and x86_64 */
@@ -73,8 +83,10 @@ static irqreturn_t timer_interrupt(int i
return IRQ_HANDLED;
}
-/* calibrate_cpu is used on systems with fixed rate TSCs to determine
- * processor frequency */
+/*
+ * calibrate_cpu is used on systems with fixed rate TSCs to determine
+ * processor frequency
+ */
#define TICK_COUNT 100000000
unsigned long __init calibrate_cpu(void)
{
@@ -121,18 +133,24 @@ unsigned long __init calibrate_cpu(void)
return pmc_now * tsc_khz / (tsc_now - tsc_start);
}
-static struct irqaction irq0 = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER,
- .name = "timer"
+static struct irqaction irq0 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+ .name = "timer"
};
+void __init setup_default_timer_irq(void)
+{
+ irq0.mask = cpumask_of_cpu(0);
+ setup_irq(0, &irq0);
+}
+
+/* Default timer init function */
void __init hpet_time_init(void)
{
if (!hpet_enable())
setup_pit_timer();
-
- setup_irq(0, &irq0);
+ setup_default_timer_irq();
}
static void x86_late_time_init(void)
@@ -140,6 +158,10 @@ static void x86_late_time_init(void)
platform_setup.timers.timer_init();
}
+/*
+ * Initialize TSC and delay the periodic timer init to
+ * late x86_late_time_init() so ioremap works.
+ */
void __init time_init(void)
{
tsc_init();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 27/32] x86: Move calibrate_cpu to tsc.c
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (25 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 26/32] x86: Make timer setup and global variables the same in time_32/64.c Thomas Gleixner
@ 2009-08-21 21:31 ` Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 28/32] x86: time_32/64.c unify profile_pc Thomas Gleixner
` (6 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:31 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-calibrate-cpu-to-tsc.patch --]
[-- Type: text/plain, Size: 5578 bytes --]
Move the code where it's only user is. Also we need to look whether
this hardwired hackery might interfere with perfcounters.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/time.h | 2 -
arch/x86/kernel/time_32.c | 1
arch/x86/kernel/time_64.c | 51 ---------------------------------------
arch/x86/kernel/tsc.c | 57 ++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 55 insertions(+), 56 deletions(-)
Index: linux-2.6/arch/x86/include/asm/time.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/time.h
+++ linux-2.6/arch/x86/include/asm/time.h
@@ -57,6 +57,4 @@ extern void time_init(void);
#endif /* CONFIG_PARAVIRT */
-extern unsigned long __init calibrate_cpu(void);
-
#endif /* _ASM_X86_TIME_H */
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -20,7 +20,6 @@
#include <asm/timer.h>
#include <asm/hpet.h>
#include <asm/time.h>
-#include <asm/nmi.h>
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
int timer_ack;
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -20,7 +20,6 @@
#include <asm/timer.h>
#include <asm/hpet.h>
#include <asm/time.h>
-#include <asm/nmi.h>
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
int timer_ack;
@@ -83,56 +82,6 @@ static irqreturn_t timer_interrupt(int i
return IRQ_HANDLED;
}
-/*
- * calibrate_cpu is used on systems with fixed rate TSCs to determine
- * processor frequency
- */
-#define TICK_COUNT 100000000
-unsigned long __init calibrate_cpu(void)
-{
- int tsc_start, tsc_now;
- int i, no_ctr_free;
- unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
- unsigned long flags;
-
- for (i = 0; i < 4; i++)
- if (avail_to_resrv_perfctr_nmi_bit(i))
- break;
- no_ctr_free = (i == 4);
- if (no_ctr_free) {
- WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
- "cpu_khz value may be incorrect.\n");
- i = 3;
- rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
- wrmsrl(MSR_K7_EVNTSEL3, 0);
- rdmsrl(MSR_K7_PERFCTR3, pmc3);
- } else {
- reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
- reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
- }
- local_irq_save(flags);
- /* start measuring cycles, incrementing from 0 */
- wrmsrl(MSR_K7_PERFCTR0 + i, 0);
- wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
- rdtscl(tsc_start);
- do {
- rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
- tsc_now = get_cycles();
- } while ((tsc_now - tsc_start) < TICK_COUNT);
-
- local_irq_restore(flags);
- if (no_ctr_free) {
- wrmsrl(MSR_K7_EVNTSEL3, 0);
- wrmsrl(MSR_K7_PERFCTR3, pmc3);
- wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
- } else {
- release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
- release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
- }
-
- return pmc_now * tsc_khz / (tsc_now - tsc_start);
-}
-
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
Index: linux-2.6/arch/x86/kernel/tsc.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/tsc.c
+++ linux-2.6/arch/x86/kernel/tsc.c
@@ -17,6 +17,7 @@
#include <asm/time.h>
#include <asm/delay.h>
#include <asm/hypervisor.h>
+#include <asm/nmi.h>
unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
EXPORT_SYMBOL(cpu_khz);
@@ -852,6 +853,60 @@ static void __init init_tsc_clocksource(
clocksource_register(&clocksource_tsc);
}
+#ifdef CONFIG_X86_64
+/*
+ * calibrate_cpu is used on systems with fixed rate TSCs to determine
+ * processor frequency
+ */
+#define TICK_COUNT 100000000
+static unsigned long __init calibrate_cpu(void)
+{
+ int tsc_start, tsc_now;
+ int i, no_ctr_free;
+ unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
+ unsigned long flags;
+
+ for (i = 0; i < 4; i++)
+ if (avail_to_resrv_perfctr_nmi_bit(i))
+ break;
+ no_ctr_free = (i == 4);
+ if (no_ctr_free) {
+ WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
+ "cpu_khz value may be incorrect.\n");
+ i = 3;
+ rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
+ wrmsrl(MSR_K7_EVNTSEL3, 0);
+ rdmsrl(MSR_K7_PERFCTR3, pmc3);
+ } else {
+ reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+ reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+ }
+ local_irq_save(flags);
+ /* start measuring cycles, incrementing from 0 */
+ wrmsrl(MSR_K7_PERFCTR0 + i, 0);
+ wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
+ rdtscl(tsc_start);
+ do {
+ rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
+ tsc_now = get_cycles();
+ } while ((tsc_now - tsc_start) < TICK_COUNT);
+
+ local_irq_restore(flags);
+ if (no_ctr_free) {
+ wrmsrl(MSR_K7_EVNTSEL3, 0);
+ wrmsrl(MSR_K7_PERFCTR3, pmc3);
+ wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
+ } else {
+ release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+ release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+ }
+
+ return pmc_now * tsc_khz / (tsc_now - tsc_start);
+}
+#else
+static inline unsigned long calibrate_cpu(void) { return cpu_khz; }
+#endif
+
void __init tsc_init(void)
{
u64 lpj;
@@ -870,11 +925,9 @@ void __init tsc_init(void)
return;
}
-#ifdef CONFIG_X86_64
if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD))
cpu_khz = calibrate_cpu();
-#endif
printk("Detected %lu.%03lu MHz processor.\n",
(unsigned long)cpu_khz / 1000,
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 28/32] x86: time_32/64.c unify profile_pc
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (26 preceding siblings ...)
2009-08-21 21:31 ` [RFC patch 27/32] x86: Move calibrate_cpu to tsc.c Thomas Gleixner
@ 2009-08-21 21:32 ` Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 29/32] x86: Replace the now identical time_32/64.c by time.c Thomas Gleixner
` (5 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:32 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-time-unify-profiling.patch --]
[-- Type: text/plain, Size: 2200 bytes --]
The code is identical except for the formatting and a useless
#ifdef. Make it the same.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/time_32.c | 13 ++++++-------
arch/x86/kernel/time_64.c | 8 +++++---
2 files changed, 11 insertions(+), 10 deletions(-)
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ linux-2.6/arch/x86/kernel/time_32.c
@@ -33,23 +33,22 @@ unsigned long profile_pc(struct pt_regs
{
unsigned long pc = instruction_pointer(regs);
-#ifdef CONFIG_SMP
if (!user_mode_vm(regs) && in_lock_functions(pc)) {
#ifdef CONFIG_FRAME_POINTER
return *(unsigned long *)(regs->bp + sizeof(long));
#else
- unsigned long *sp = (unsigned long *)®s->sp;
-
- /* Return address is either directly at stack pointer
- or above a saved flags. Eflags has bits 22-31 zero,
- kernel addresses don't. */
+ unsigned long *sp = (unsigned long *)regs->sp;
+ /*
+ * Return address is either directly at stack pointer
+ * or above a saved flags. Eflags has bits 22-31 zero,
+ * kernel addresses don't.
+ */
if (sp[0] >> 22)
return sp[0];
if (sp[1] >> 22)
return sp[1];
#endif
}
-#endif
return pc;
}
EXPORT_SYMBOL(profile_pc);
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -33,14 +33,16 @@ unsigned long profile_pc(struct pt_regs
{
unsigned long pc = instruction_pointer(regs);
- /* Assume the lock function has either no stack frame or a copy
- of flags from PUSHF
- Eflags always has bits 22 and up cleared unlike kernel addresses. */
if (!user_mode_vm(regs) && in_lock_functions(pc)) {
#ifdef CONFIG_FRAME_POINTER
return *(unsigned long *)(regs->bp + sizeof(long));
#else
unsigned long *sp = (unsigned long *)regs->sp;
+ /*
+ * Return address is either directly at stack pointer
+ * or above a saved flags. Eflags has bits 22-31 zero,
+ * kernel addresses don't.
+ */
if (sp[0] >> 22)
return sp[0];
if (sp[1] >> 22)
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 29/32] x86: Replace the now identical time_32/64.c by time.c
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (27 preceding siblings ...)
2009-08-21 21:32 ` [RFC patch 28/32] x86: time_32/64.c unify profile_pc Thomas Gleixner
@ 2009-08-21 21:32 ` Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 30/32] x86: Move tsc_calibration to platform Thomas Gleixner
` (4 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:32 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-remove-the-redundant-copy.patch --]
[-- Type: text/plain, Size: 10098 bytes --]
Remove the redundant copy.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/Makefile | 2
arch/x86/kernel/time.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/time_32.c | 120 ----------------------------------------------
arch/x86/kernel/time_64.c | 120 ----------------------------------------------
4 files changed, 121 insertions(+), 241 deletions(-)
Index: linux-2.6/arch/x86/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/x86/kernel/Makefile
+++ linux-2.6/arch/x86/kernel/Makefile
@@ -31,7 +31,7 @@ GCOV_PROFILE_paravirt.o := n
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
-obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o
+obj-y += time.o ioport.o ldt.o dumpstack.o
obj-y += setup.o platform_setup.o i8259.o irqinit.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
obj-$(CONFIG_X86_32) += probe_roms_32.o
Index: linux-2.6/arch/x86/kernel/time.c
===================================================================
--- /dev/null
+++ linux-2.6/arch/x86/kernel/time.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1991,1992,1995 Linus Torvalds
+ * Copyright (c) 1994 Alan Modra
+ * Copyright (c) 1995 Markus Kuhn
+ * Copyright (c) 1996 Ingo Molnar
+ * Copyright (c) 1998 Andrea Arcangeli
+ * Copyright (c) 2002,2006 Vojtech Pavlik
+ * Copyright (c) 2003 Andi Kleen
+ *
+ */
+
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/mca.h>
+
+#include <asm/platform.h>
+#include <asm/i8259.h>
+#include <asm/i8253.h>
+#include <asm/timer.h>
+#include <asm/hpet.h>
+#include <asm/time.h>
+
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
+int timer_ack;
+#endif
+
+#ifdef CONFIG_X86_64
+volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+#endif
+
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ if (!user_mode_vm(regs) && in_lock_functions(pc)) {
+#ifdef CONFIG_FRAME_POINTER
+ return *(unsigned long *)(regs->bp + sizeof(long));
+#else
+ unsigned long *sp = (unsigned long *)regs->sp;
+ /*
+ * Return address is either directly at stack pointer
+ * or above a saved flags. Eflags has bits 22-31 zero,
+ * kernel addresses don't.
+ */
+ if (sp[0] >> 22)
+ return sp[0];
+ if (sp[1] >> 22)
+ return sp[1];
+#endif
+ }
+ return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+/*
+ * Default timer interrupt handler for PIT/HPET
+ */
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ /* Keep nmi watchdog up to date */
+ inc_irq_stat(irq0_irqs);
+
+ /* Optimized out for !IO_APIC and x86_64 */
+ if (timer_ack) {
+ /*
+ * Subtle, when I/O APICs are used we have to ack timer IRQ
+ * manually to deassert NMI lines for the watchdog if run
+ * on an 82489DX-based system.
+ */
+ spin_lock(&i8259A_lock);
+ outb(0x0c, PIC_MASTER_OCW3);
+ /* Ack the IRQ; AEOI will end it automatically. */
+ inb(PIC_MASTER_POLL);
+ spin_unlock(&i8259A_lock);
+ }
+
+ global_clock_event->event_handler(global_clock_event);
+
+ /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
+ if (MCA_bus)
+ outb_p(inb_p(0x61)| 0x80, 0x61);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq0 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+ .name = "timer"
+};
+
+void __init setup_default_timer_irq(void)
+{
+ irq0.mask = cpumask_of_cpu(0);
+ setup_irq(0, &irq0);
+}
+
+/* Default timer init function */
+void __init hpet_time_init(void)
+{
+ if (!hpet_enable())
+ setup_pit_timer();
+ setup_default_timer_irq();
+}
+
+static void x86_late_time_init(void)
+{
+ platform_setup.timers.timer_init();
+}
+
+/*
+ * Initialize TSC and delay the periodic timer init to
+ * late x86_late_time_init() so ioremap works.
+ */
+void __init time_init(void)
+{
+ tsc_init();
+ late_time_init = x86_late_time_init;
+}
Index: linux-2.6/arch/x86/kernel/time_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_32.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 1991,1992,1995 Linus Torvalds
- * Copyright (c) 1994 Alan Modra
- * Copyright (c) 1995 Markus Kuhn
- * Copyright (c) 1996 Ingo Molnar
- * Copyright (c) 1998 Andrea Arcangeli
- * Copyright (c) 2002,2006 Vojtech Pavlik
- * Copyright (c) 2003 Andi Kleen
- *
- */
-
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/mca.h>
-
-#include <asm/platform.h>
-#include <asm/i8259.h>
-#include <asm/i8253.h>
-#include <asm/timer.h>
-#include <asm/hpet.h>
-#include <asm/time.h>
-
-#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
-int timer_ack;
-#endif
-
-#ifdef CONFIG_X86_64
-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
-#endif
-
-unsigned long profile_pc(struct pt_regs *regs)
-{
- unsigned long pc = instruction_pointer(regs);
-
- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
- return *(unsigned long *)(regs->bp + sizeof(long));
-#else
- unsigned long *sp = (unsigned long *)regs->sp;
- /*
- * Return address is either directly at stack pointer
- * or above a saved flags. Eflags has bits 22-31 zero,
- * kernel addresses don't.
- */
- if (sp[0] >> 22)
- return sp[0];
- if (sp[1] >> 22)
- return sp[1];
-#endif
- }
- return pc;
-}
-EXPORT_SYMBOL(profile_pc);
-
-/*
- * Default timer interrupt handler for PIT/HPET
- */
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- /* Keep nmi watchdog up to date */
- inc_irq_stat(irq0_irqs);
-
- /* Optimized out for !IO_APIC and x86_64 */
- if (timer_ack) {
- /*
- * Subtle, when I/O APICs are used we have to ack timer IRQ
- * manually to deassert NMI lines for the watchdog if run
- * on an 82489DX-based system.
- */
- spin_lock(&i8259A_lock);
- outb(0x0c, PIC_MASTER_OCW3);
- /* Ack the IRQ; AEOI will end it automatically. */
- inb(PIC_MASTER_POLL);
- spin_unlock(&i8259A_lock);
- }
-
- global_clock_event->event_handler(global_clock_event);
-
- /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
- if (MCA_bus)
- outb_p(inb_p(0x61)| 0x80, 0x61);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction irq0 = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
- .name = "timer"
-};
-
-void __init setup_default_timer_irq(void)
-{
- irq0.mask = cpumask_of_cpu(0);
- setup_irq(0, &irq0);
-}
-
-/* Default timer init function */
-void __init hpet_time_init(void)
-{
- if (!hpet_enable())
- setup_pit_timer();
- setup_default_timer_irq();
-}
-
-static void x86_late_time_init(void)
-{
- platform_setup.timers.timer_init();
-}
-
-/*
- * Initialize TSC and delay the periodic timer init to
- * late x86_late_time_init() so ioremap works.
- */
-void __init time_init(void)
-{
- tsc_init();
- late_time_init = x86_late_time_init;
-}
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 1991,1992,1995 Linus Torvalds
- * Copyright (c) 1994 Alan Modra
- * Copyright (c) 1995 Markus Kuhn
- * Copyright (c) 1996 Ingo Molnar
- * Copyright (c) 1998 Andrea Arcangeli
- * Copyright (c) 2002,2006 Vojtech Pavlik
- * Copyright (c) 2003 Andi Kleen
- *
- */
-
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/mca.h>
-
-#include <asm/platform.h>
-#include <asm/i8259.h>
-#include <asm/i8253.h>
-#include <asm/timer.h>
-#include <asm/hpet.h>
-#include <asm/time.h>
-
-#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
-int timer_ack;
-#endif
-
-#ifdef CONFIG_X86_64
-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
-#endif
-
-unsigned long profile_pc(struct pt_regs *regs)
-{
- unsigned long pc = instruction_pointer(regs);
-
- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
- return *(unsigned long *)(regs->bp + sizeof(long));
-#else
- unsigned long *sp = (unsigned long *)regs->sp;
- /*
- * Return address is either directly at stack pointer
- * or above a saved flags. Eflags has bits 22-31 zero,
- * kernel addresses don't.
- */
- if (sp[0] >> 22)
- return sp[0];
- if (sp[1] >> 22)
- return sp[1];
-#endif
- }
- return pc;
-}
-EXPORT_SYMBOL(profile_pc);
-
-/*
- * Default timer interrupt handler for PIT/HPET
- */
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- /* Keep nmi watchdog up to date */
- inc_irq_stat(irq0_irqs);
-
- /* Optimized out for !IO_APIC and x86_64 */
- if (timer_ack) {
- /*
- * Subtle, when I/O APICs are used we have to ack timer IRQ
- * manually to deassert NMI lines for the watchdog if run
- * on an 82489DX-based system.
- */
- spin_lock(&i8259A_lock);
- outb(0x0c, PIC_MASTER_OCW3);
- /* Ack the IRQ; AEOI will end it automatically. */
- inb(PIC_MASTER_POLL);
- spin_unlock(&i8259A_lock);
- }
-
- global_clock_event->event_handler(global_clock_event);
-
- /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
- if (MCA_bus)
- outb_p(inb_p(0x61)| 0x80, 0x61);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction irq0 = {
- .handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
- .name = "timer"
-};
-
-void __init setup_default_timer_irq(void)
-{
- irq0.mask = cpumask_of_cpu(0);
- setup_irq(0, &irq0);
-}
-
-/* Default timer init function */
-void __init hpet_time_init(void)
-{
- if (!hpet_enable())
- setup_pit_timer();
- setup_default_timer_irq();
-}
-
-static void x86_late_time_init(void)
-{
- platform_setup.timers.timer_init();
-}
-
-/*
- * Initialize TSC and delay the periodic timer init to
- * late x86_late_time_init() so ioremap works.
- */
-void __init time_init(void)
-{
- tsc_init();
- late_time_init = x86_late_time_init;
-}
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 30/32] x86: Move tsc_calibration to platform
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (28 preceding siblings ...)
2009-08-21 21:32 ` [RFC patch 29/32] x86: Replace the now identical time_32/64.c by time.c Thomas Gleixner
@ 2009-08-21 21:32 ` Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 31/32] init: Move sched_clock_init after late_time_init Thomas Gleixner
` (3 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:32 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-tsc-calibration-to-platform.patch --]
[-- Type: text/plain, Size: 12940 bytes --]
TSC calibration is modified by the vmware hypervisor and paravirt by
separate means. Moorestown wants to add its own calibration routine as
well. So make calibrate_tsc a proper platform function and override it
by paravirt or by the early setup of the vmware hypervisor.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/hypervisor.h | 2 +-
arch/x86/include/asm/paravirt.h | 2 --
arch/x86/include/asm/platform.h | 2 ++
arch/x86/include/asm/timer.h | 5 -----
arch/x86/include/asm/tsc.h | 3 ++-
arch/x86/include/asm/vmware.h | 2 +-
arch/x86/kernel/cpu/hypervisor.c | 14 +++++++-------
arch/x86/kernel/cpu/vmware.c | 35 +++++++++++++++++++----------------
arch/x86/kernel/kvmclock.c | 2 +-
arch/x86/kernel/paravirt.c | 1 -
arch/x86/kernel/platform_setup.c | 2 ++
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/tsc.c | 10 ++--------
arch/x86/kernel/vmi_32.c | 2 +-
arch/x86/kernel/vmiclock_32.c | 2 +-
arch/x86/lguest/boot.c | 2 +-
arch/x86/xen/enlighten.c | 2 +-
17 files changed, 42 insertions(+), 48 deletions(-)
Index: linux-2.6/arch/x86/include/asm/hypervisor.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/hypervisor.h
+++ linux-2.6/arch/x86/include/asm/hypervisor.h
@@ -20,7 +20,7 @@
#ifndef ASM_X86__HYPERVISOR_H
#define ASM_X86__HYPERVISOR_H
-extern unsigned long get_hypervisor_tsc_freq(void);
extern void init_hypervisor(struct cpuinfo_x86 *c);
+extern void init_hypervisor_platform(void);
#endif
Index: linux-2.6/arch/x86/include/asm/paravirt.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/paravirt.h
+++ linux-2.6/arch/x86/include/asm/paravirt.h
@@ -103,7 +103,6 @@ struct pv_time_ops {
int (*set_wallclock)(unsigned long);
unsigned long long (*sched_clock)(void);
- unsigned long (*get_tsc_khz)(void);
};
struct pv_cpu_ops {
@@ -867,7 +866,6 @@ static inline unsigned long long paravir
{
return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
}
-#define calibrate_tsc() (pv_time_ops.get_tsc_khz())
static inline unsigned long long paravirt_read_pmc(int counter)
{
Index: linux-2.6/arch/x86/include/asm/platform.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/platform.h
+++ linux-2.6/arch/x86/include/asm/platform.h
@@ -90,11 +90,13 @@ struct platform_setup_paging {
* boot cpu
* @tsc_pre_init: platform function called before TSC init
* @timer_init: initialize the platform timer (default PIT/HPET)
+ * @calibrate_tsc: calibrate TSC
*/
struct platform_setup_timers {
void (*setup_percpu_clockev)(void);
void (*tsc_pre_init)(void);
void (*timer_init)(void);
+ unsigned long (*calibrate_tsc)(void);
};
/**
Index: linux-2.6/arch/x86/include/asm/timer.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/timer.h
+++ linux-2.6/arch/x86/include/asm/timer.h
@@ -8,7 +8,6 @@
#define TICK_SIZE (tick_nsec / 1000)
unsigned long long native_sched_clock(void);
-unsigned long native_calibrate_tsc(void);
extern int recalibrate_cpu_khz(void);
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
@@ -19,10 +18,6 @@ extern int timer_ack;
extern int no_timer_check;
-#ifndef CONFIG_PARAVIRT
-#define calibrate_tsc() native_calibrate_tsc()
-#endif
-
/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
* basic equation:
Index: linux-2.6/arch/x86/include/asm/tsc.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/tsc.h
+++ linux-2.6/arch/x86/include/asm/tsc.h
@@ -48,7 +48,8 @@ static __always_inline cycles_t vget_cyc
extern void tsc_init(void);
extern void mark_tsc_unstable(char *reason);
extern int unsynchronized_tsc(void);
-int check_tsc_unstable(void);
+extern int check_tsc_unstable(void);
+extern unsigned long native_calibrate_tsc(void);
/*
* Boot-time check whether the TSCs are synchronized across
Index: linux-2.6/arch/x86/include/asm/vmware.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/vmware.h
+++ linux-2.6/arch/x86/include/asm/vmware.h
@@ -20,7 +20,7 @@
#ifndef ASM_X86__VMWARE_H
#define ASM_X86__VMWARE_H
-extern unsigned long vmware_get_tsc_khz(void);
+extern void vmware_platform_setup(void);
extern int vmware_platform(void);
extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
Index: linux-2.6/arch/x86/kernel/cpu/hypervisor.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/hypervisor.c
+++ linux-2.6/arch/x86/kernel/cpu/hypervisor.c
@@ -35,13 +35,6 @@ detect_hypervisor_vendor(struct cpuinfo_
}
}
-unsigned long get_hypervisor_tsc_freq(void)
-{
- if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
- return vmware_get_tsc_khz();
- return 0;
-}
-
static inline void __cpuinit
hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
{
@@ -56,3 +49,10 @@ void __cpuinit init_hypervisor(struct cp
detect_hypervisor_vendor(c);
hypervisor_set_feature_bits(c);
}
+
+void __init init_hypervisor_platform(void)
+{
+ init_hypervisor(&boot_cpu_data);
+ if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
+ vmware_platform_setup();
+}
Index: linux-2.6/arch/x86/kernel/cpu/vmware.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/vmware.c
+++ linux-2.6/arch/x86/kernel/cpu/vmware.c
@@ -24,6 +24,7 @@
#include <linux/dmi.h>
#include <asm/div64.h>
#include <asm/vmware.h>
+#include <asm/platform.h>
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
@@ -47,19 +48,27 @@ static inline int __vmware_platform(void
return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
}
-static unsigned long __vmware_get_tsc_khz(void)
+static unsigned long vmware_get_tsc_khz(void)
{
- uint64_t tsc_hz;
- uint32_t eax, ebx, ecx, edx;
+ uint64_t tsc_hz;
+ uint32_t eax, ebx, ecx, edx;
+
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+
+ tsc_hz = eax | (((uint64_t)ebx) << 32);
+ do_div(tsc_hz, 1000);
+ BUG_ON(tsc_hz >> 32);
+ return tsc_hz;
+}
+
+void __init vmware_platform_setup(void)
+{
+ uint32_t eax, ebx, ecx, edx;
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
- if (ebx == UINT_MAX)
- return 0;
- tsc_hz = eax | (((uint64_t)ebx) << 32);
- do_div(tsc_hz, 1000);
- BUG_ON(tsc_hz >> 32);
- return tsc_hz;
+ if (ebx != UINT_MAX)
+ platform_setup.timers.calibrate_tsc = vmware_get_tsc_khz;
}
/*
@@ -87,12 +96,6 @@ int vmware_platform(void)
return 0;
}
-unsigned long vmware_get_tsc_khz(void)
-{
- BUG_ON(!vmware_platform());
- return __vmware_get_tsc_khz();
-}
-
/*
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
* Still, due to timing difference when running on virtual cpus, the TSC can
Index: linux-2.6/arch/x86/kernel/kvmclock.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/kvmclock.c
+++ linux-2.6/arch/x86/kernel/kvmclock.c
@@ -187,7 +187,7 @@ void __init kvmclock_init(void)
pv_time_ops.get_wallclock = kvm_get_wallclock;
pv_time_ops.set_wallclock = kvm_set_wallclock;
pv_time_ops.sched_clock = kvm_clock_read;
- pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
+ platform_setup.timers.calibrate_tsc = kvm_get_tsc_khz;
#ifdef CONFIG_X86_LOCAL_APIC
platform_cpuhotplug_setup.setup_percpu_clockev =
kvm_setup_secondary_clock;
Index: linux-2.6/arch/x86/kernel/paravirt.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/paravirt.c
+++ linux-2.6/arch/x86/kernel/paravirt.c
@@ -309,7 +309,6 @@ struct pv_time_ops pv_time_ops = {
.get_wallclock = native_get_wallclock,
.set_wallclock = native_set_wallclock,
.sched_clock = native_sched_clock,
- .get_tsc_khz = native_calibrate_tsc,
};
struct pv_irq_ops pv_irq_ops = {
Index: linux-2.6/arch/x86/kernel/platform_setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/platform_setup.c
+++ linux-2.6/arch/x86/kernel/platform_setup.c
@@ -12,6 +12,7 @@
#include <asm/e820.h>
#include <asm/time.h>
#include <asm/irq.h>
+#include <asm/tsc.h>
void __cpuinit platform_setup_noop(void) { }
void __init platform_setup_uint_noop(unsigned int unused) { }
@@ -59,6 +60,7 @@ struct __initdata platform_setup_ops pla
.setup_percpu_clockev = setup_boot_APIC_clock,
.tsc_pre_init = platform_setup_noop,
.timer_init = hpet_time_init,
+ .calibrate_tsc = native_calibrate_tsc,
},
.quirks = {
Index: linux-2.6/arch/x86/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -818,7 +818,7 @@ void __init setup_arch(char **cmdline_p)
* VMware detection requires dmi to be available, so this
* needs to be done after dmi_scan_machine, for the BP.
*/
- init_hypervisor(&boot_cpu_data);
+ init_hypervisor_platform();
platform_setup.resources.probe_roms();
Index: linux-2.6/arch/x86/kernel/tsc.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/tsc.c
+++ linux-2.6/arch/x86/kernel/tsc.c
@@ -401,15 +401,9 @@ unsigned long native_calibrate_tsc(void)
{
u64 tsc1, tsc2, delta, ref1, ref2;
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
- unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
+ unsigned long flags, latch, ms, fast_calibrate;
int hpet = is_hpet_enabled(), i, loopmin;
- hv_tsc_khz = get_hypervisor_tsc_freq();
- if (hv_tsc_khz) {
- printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
- return hv_tsc_khz;
- }
-
local_irq_save(flags);
fast_calibrate = quick_pit_calibrate();
local_irq_restore(flags);
@@ -917,7 +911,7 @@ void __init tsc_init(void)
if (!cpu_has_tsc)
return;
- tsc_khz = calibrate_tsc();
+ tsc_khz = platform_setup.timers.calibrate_tsc();
cpu_khz = tsc_khz;
if (!tsc_khz) {
Index: linux-2.6/arch/x86/kernel/vmi_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmi_32.c
+++ linux-2.6/arch/x86/kernel/vmi_32.c
@@ -826,7 +826,7 @@ static inline int __init activate_vmi(vo
vmi_time_ap_init;
#endif
pv_time_ops.sched_clock = vmi_sched_clock;
- pv_time_ops.get_tsc_khz = vmi_tsc_khz;
+ platform_setup.timers.calibrate_tsc = vmi_tsc_khz;
/* We have true wallclock functions; disable CMOS clock sync */
no_sync_cmos_clock = 1;
Index: linux-2.6/arch/x86/kernel/vmiclock_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/vmiclock_32.c
+++ linux-2.6/arch/x86/kernel/vmiclock_32.c
@@ -68,7 +68,7 @@ unsigned long long vmi_sched_clock(void)
return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
}
-/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
+/* platform_setup.calibrate_tsc = vmi_tsc_khz */
unsigned long vmi_tsc_khz(void)
{
unsigned long long khz;
Index: linux-2.6/arch/x86/lguest/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/lguest/boot.c
+++ linux-2.6/arch/x86/lguest/boot.c
@@ -1320,11 +1320,11 @@ __init void lguest_init(void)
/* Time operations */
pv_time_ops.get_wallclock = lguest_get_wallclock;
- pv_time_ops.get_tsc_khz = lguest_tsc_khz;
platform_setup.resources.memory_setup = lguest_memory_setup;
platform_setup.irqs.intr_init = lguest_init_IRQ;
platform_setup.timers.timer_init = lguest_time_init;
+ platform_setup.timers.calibrate_tsc = lguest_tsc_khz;
/*
* Now is a good time to look at the implementations of these functions
Index: linux-2.6/arch/x86/xen/enlighten.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/enlighten.c
+++ linux-2.6/arch/x86/xen/enlighten.c
@@ -844,7 +844,6 @@ static const struct pv_init_ops xen_init
static const struct pv_time_ops xen_time_ops __initdata = {
.set_wallclock = xen_set_wallclock,
.get_wallclock = xen_get_wallclock,
- .get_tsc_khz = xen_tsc_khz,
.sched_clock = xen_sched_clock,
};
@@ -981,6 +980,7 @@ asmlinkage void __init xen_start_kernel(
platform_setup.oem.banner = xen_banner;
platform_setup.timers.timer_init = xen_time_init;
+ platform_setup.timers.calibrate_tsc = xen_tsc_khz;
/* Override the default per cpu clockevents setup functions */
platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 31/32] init: Move sched_clock_init after late_time_init
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (29 preceding siblings ...)
2009-08-21 21:32 ` [RFC patch 30/32] x86: Move tsc_calibration to platform Thomas Gleixner
@ 2009-08-21 21:32 ` Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 32/32] x86: Move tsc_init to late_time_init Thomas Gleixner
` (2 subsequent siblings)
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:32 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun, linux-arch
[-- Attachment #1: init-move-sched-clock-init-after-late-time-init.patch --]
[-- Type: text/plain, Size: 1266 bytes --]
Some architectures initialize clocks and timers in late_time_init and
x86 wants to do the same to avoid FIXMAP hackery for calibrating the
TSC. That would result in undefined sched_clock readout and wreckaged
printk timestamps again. We probably have those already on archs which
do all their time/clock setup in late_time_init.
There is no harm to move that after late_time_init except that a few
more boot timestamps are stale. The scheduler is not active at that
point so no real wreckage is expected.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
---
init/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6/init/main.c
===================================================================
--- linux-2.6.orig/init/main.c
+++ linux-2.6/init/main.c
@@ -631,7 +631,6 @@ asmlinkage void __init start_kernel(void
softirq_init();
timekeeping_init();
time_init();
- sched_clock_init();
profile_init();
if (!irqs_disabled())
printk(KERN_CRIT "start_kernel(): bug: interrupts were "
@@ -682,6 +681,7 @@ asmlinkage void __init start_kernel(void
numa_policy_init();
if (late_time_init)
late_time_init();
+ sched_clock_init();
calibrate_delay();
pidmap_init();
anon_vma_init();
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC patch 32/32] x86: Move tsc_init to late_time_init
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (30 preceding siblings ...)
2009-08-21 21:32 ` [RFC patch 31/32] init: Move sched_clock_init after late_time_init Thomas Gleixner
@ 2009-08-21 21:32 ` Thomas Gleixner
2009-08-21 22:19 ` [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Jeremy Fitzhardinge
2009-08-22 10:57 ` Ingo Molnar
33 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 21:32 UTC (permalink / raw)
To: LKML
Cc: x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
[-- Attachment #1: x86-move-tsc-init-to-late-time-init.patch --]
[-- Type: text/plain, Size: 971 bytes --]
We do not need the TSC before late_time_init. Move the tsc_init to the
late time init code so we can also utilize HPET for calibration (which
we claimed to do but never did except in some older kernel
version). This also helps Moorestown to calibrate the TSC with the
AHBT timer which needs to be initialized in late_time_init like HPET.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/time.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6/arch/x86/kernel/time.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time.c
+++ linux-2.6/arch/x86/kernel/time.c
@@ -107,6 +107,7 @@ void __init hpet_time_init(void)
static void x86_late_time_init(void)
{
platform_setup.timers.timer_init();
+ tsc_init();
}
/*
@@ -115,6 +116,5 @@ static void x86_late_time_init(void)
*/
void __init time_init(void)
{
- tsc_init();
late_time_init = x86_late_time_init;
}
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (31 preceding siblings ...)
2009-08-21 21:32 ` [RFC patch 32/32] x86: Move tsc_init to late_time_init Thomas Gleixner
@ 2009-08-21 22:19 ` Jeremy Fitzhardinge
2009-08-22 10:57 ` Ingo Molnar
33 siblings, 0 replies; 53+ messages in thread
From: Jeremy Fitzhardinge @ 2009-08-21 22:19 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Pan Jacob jun
On 08/21/09 14:29, Thomas Gleixner wrote:
> The following patch series refactors the setup related x86_quirks and
> the setup related paravirt hooks and puts them into an extensible
> platform_setup infrastructure to provide a proper base for adding the
> Moorestown modifications. As a side effect it also unifies
> time_32/64.c and removes some leftovers of the pre arch/x86 era.
>
I haven't gone through the patches at all yet, but I definitely like
this direction. I've got some local patches to generalize x86_quirks a
bit, and I'm hoping that you've already subsumed them; if not, it should
be easy to extend on top of your patches.
J
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 02/32] x86: Add probe_roms to platform_setup
2009-08-21 21:29 ` [RFC patch 02/32] x86: Add probe_roms to platform_setup Thomas Gleixner
@ 2009-08-21 22:23 ` Jeremy Fitzhardinge
2009-08-21 22:36 ` Thomas Gleixner
0 siblings, 1 reply; 53+ messages in thread
From: Jeremy Fitzhardinge @ 2009-08-21 22:23 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Pan Jacob jun
On 08/21/09 14:29, Thomas Gleixner wrote:
[argh attachments]
> probe_roms is only used on 32bit. Add it to the platform_setup code
> and remove the #ifdefs.
>
> Default initializer is platform_setup_noop() which is overridden in
> the 32bit boot code.
>
>
I realize you're aiming to make this transform have no functional
side-effects, but is there a good reason why probe_roms *couldn't* be
done in 64-bit? It seems to me that its useful for coverage
completeness to have the 32 and 64 bit do the same thing even if its
sometimes redundant.
J
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function
2009-08-21 21:30 ` [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function Thomas Gleixner
@ 2009-08-21 22:30 ` Jeremy Fitzhardinge
2009-08-21 23:42 ` Thomas Gleixner
0 siblings, 1 reply; 53+ messages in thread
From: Jeremy Fitzhardinge @ 2009-08-21 22:30 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Pan Jacob jun
On 08/21/09 14:30, Thomas Gleixner wrote:
> ARCH_SETUP is a horrible hack of paravirt/xen which is way nicer to
> read as a platform setup function.
>
Not really correct; its a left-over from the old subarch stuff. But it
was certainly never very pretty.
J
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 02/32] x86: Add probe_roms to platform_setup
2009-08-21 22:23 ` Jeremy Fitzhardinge
@ 2009-08-21 22:36 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
` (6 more replies)
0 siblings, 7 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 22:36 UTC (permalink / raw)
To: Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Pan Jacob jun
On Fri, 21 Aug 2009, Jeremy Fitzhardinge wrote:
> On 08/21/09 14:29, Thomas Gleixner wrote:
> [argh attachments]
No. :)
Content-Disposition: inline;
filename=x86-add-probe-roms-to-platform-setup.patch
> > probe_roms is only used on 32bit. Add it to the platform_setup code
> > and remove the #ifdefs.
> >
> > Default initializer is platform_setup_noop() which is overridden in
> > the 32bit boot code.
> >
> >
>
> I realize you're aiming to make this transform have no functional
> side-effects, but is there a good reason why probe_roms *couldn't* be
> done in 64-bit? It seems to me that its useful for coverage
> completeness to have the 32 and 64 bit do the same thing even if its
> sometimes redundant.
Yes. I aimed for functional equivilance in the first place and this is
a RFC so any improvements are welcome.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function
2009-08-21 22:30 ` Jeremy Fitzhardinge
@ 2009-08-21 23:42 ` Thomas Gleixner
2009-08-28 21:52 ` [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown Pan, Jacob jun
0 siblings, 1 reply; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-21 23:42 UTC (permalink / raw)
To: Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Pan Jacob jun
On Fri, 21 Aug 2009, Jeremy Fitzhardinge wrote:
> On 08/21/09 14:30, Thomas Gleixner wrote:
> > ARCH_SETUP is a horrible hack of paravirt/xen which is way nicer to
> > read as a platform setup function.
> >
>
> Not really correct; its a left-over from the old subarch stuff. But it
> was certainly never very pretty.
Oops. Sorry, I squeezed the history out of my brain and my
subconscious mind attributed it to paravirt/xen :)
Will fix the comment.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
` (32 preceding siblings ...)
2009-08-21 22:19 ` [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Jeremy Fitzhardinge
@ 2009-08-22 10:57 ` Ingo Molnar
2009-08-23 9:15 ` Thomas Gleixner
33 siblings, 1 reply; 53+ messages in thread
From: Ingo Molnar @ 2009-08-22 10:57 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun, Linus Torvalds
* Thomas Gleixner <tglx@linutronix.de> wrote:
[...]
> The following patch series refactors the setup related x86_quirks
> and the setup related paravirt hooks and puts them into an
> extensible platform_setup infrastructure to provide a proper base
> for adding the Moorestown modifications. As a side effect it also
> unifies time_32/64.c and removes some leftovers of the pre
> arch/x86 era.
>
> Note, this is not a replacement for paravirt_ops. It is just
> replacing the setup related paravirt stuff so it can be reused for
> other platforms though I have to say that it removes a fair amount
> of obscurity which was introduced by paravirt & Co.
> 47 files changed, 622 insertions(+), 808 deletions(-)
Very nice!
One small detail, before we spread out these patches. While looking
at the patches i noticed that at places our new x86 init namespace
is very long:
> + platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
> + platform_cpuhotplug_setup.setup_percpu_clockev = platform_setup_noop;
> +
I think we should shorten the name-space a bit - we'll use it in a
_lot_ of places, so the shorter, the better and the easier to use.
I'd suggest something like:
x86_init.timers.init_percpu_clockev = x86_init_noop;
x86_cpuhotplug_init.init_percpu_clockev = x86_init_noop;
( This also has the advantage that 'init' is the general term we use
for kernel structure initialization - 'setup' is a more
restrictive term we use related to bootloading, most of the time. )
An even shorter form would be to use 'x86' as a general template for
platform details:
x86.timers.init_percpu_ce = x86_init_noop;
x86_cpuhotplug.init_percpu_ce = x86_init_noop;
this is even shorter, plus it allows us to put runtime details into
this structure as well. Note that the fields themselves
(init_percpu_clockev) already signal the 'init' property
sufficiently. Plus 'ce' is an existing, well-known abbreviation for
clockevents. (but 'clockev' would be good too - i might be pushing
it)
What do you think?
Ingo
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms
2009-08-22 10:57 ` Ingo Molnar
@ 2009-08-23 9:15 ` Thomas Gleixner
0 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-23 9:15 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun, Linus Torvalds
On Sat, 22 Aug 2009, Ingo Molnar wrote:
> * Thomas Gleixner <tglx@linutronix.de> wrote:
> > 47 files changed, 622 insertions(+), 808 deletions(-)
>
> Very nice!
>
> One small detail, before we spread out these patches. While looking
> at the patches i noticed that at places our new x86 init namespace
> is very long:
>
> > + platform_setup.timers.setup_percpu_clockev = platform_setup_noop;
> > + platform_cpuhotplug_setup.setup_percpu_clockev = platform_setup_noop;
> > +
>
> I think we should shorten the name-space a bit - we'll use it in a
> _lot_ of places, so the shorter, the better and the easier to use.
>
> I'd suggest something like:
>
> x86_init.timers.init_percpu_clockev = x86_init_noop;
> x86_cpuhotplug_init.init_percpu_clockev = x86_init_noop;
>
> ( This also has the advantage that 'init' is the general term we use
> for kernel structure initialization - 'setup' is a more
> restrictive term we use related to bootloading, most of the time. )
Fair enough.
> An even shorter form would be to use 'x86' as a general template for
> platform details:
>
> x86.timers.init_percpu_ce = x86_init_noop;
> x86_cpuhotplug.init_percpu_ce = x86_init_noop;
>
> this is even shorter, plus it allows us to put runtime details into
> this structure as well. Note that the fields themselves
We should have a separate struct for runtime details otherwise we need
to keep the full init stuff around forever instead of freeing
it. That's why I already have that separate cpuhotplug struct.
> (init_percpu_clockev) already signal the 'init' property
> sufficiently. Plus 'ce' is an existing, well-known abbreviation for
> clockevents. (but 'clockev' would be good too - i might be pushing
> it)
Yes you do. Next you suggest to have x86_i.pcpu_ce :)
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC patch 21/32] x86: Add timer_init to platform
2009-08-21 21:31 ` [RFC patch 21/32] x86: Add timer_init " Thomas Gleixner
@ 2009-08-24 6:48 ` Andrey Panin
0 siblings, 0 replies; 53+ messages in thread
From: Andrey Panin @ 2009-08-24 6:48 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Jeremy Fitzhardinge, Rusty Russell, Alok N Kataria,
Pan Jacob jun
On 233, 08 21, 2009 at 09:31:20 -0000, Thomas Gleixner wrote:
> The timer init code is convoluted with several quirks and the paravirt
> timer chooser. Figuring out which code path is actually taken is not
> for the faint hearted.
>
> Move the numaq TSC quirk to tsc_pre_init platform function and replace
> the paravirt time chooser and the remaining x86 quirk with a simple
> platform setup function.
> Index: linux-2.6/arch/x86/kernel/visws_quirks.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/visws_quirks.c
> +++ linux-2.6/arch/x86/kernel/visws_quirks.c
> @@ -30,6 +30,7 @@
> #include <asm/setup.h>
> #include <asm/apic.h>
> #include <asm/e820.h>
> +#include <asm/time.h>
> #include <asm/io.h>
>
> #include <linux/kernel_stat.h>
> @@ -53,8 +54,10 @@ int is_visws_box(void)
> return visws_board_type >= 0;
> }
>
> -static int __init visws_time_init(void)
> +static void __init visws_time_init(void)
> {
> + hpet_time_init();
What's the purpose of this line ? It's highly unlikely that there is HPET hidden
somewhere inside VisWs :)
> printk(KERN_INFO "Starting Cobalt Timer system clock\n");
>
> /* Set the countdown value */
> @@ -65,12 +68,6 @@ static int __init visws_time_init(void)
>
> /* Enable (unmask) the timer interrupt */
> co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
> -
> - /*
> - * Zero return means the generic timer setup code will set up
> - * the standard vector:
> - */
> - return 0;
> }
>
^ permalink raw reply [flat|nested] 53+ messages in thread
* [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction
2009-08-21 22:36 ` Thomas Gleixner
@ 2009-08-28 21:52 ` Pan, Jacob jun
2009-08-29 16:59 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 2/7] x86: introduce a set of platform feature flags Pan, Jacob jun
` (5 subsequent siblings)
6 siblings, 1 reply; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:52 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
Based on platform_setup patchset posted by tglx (http://lkml.org/lkml/2009/8/21/358)
These Moorestown patches have become much simplified once ported to the new
platform_setup layer.
Now the platform feature flags are less useful, in fact they
are only used in separating ioapic and 8259 now, so once the interrupt
controller code is drivernized, we would not need the platform feature flags
in the core.
Thanks,
Jacob
^ permalink raw reply [flat|nested] 53+ messages in thread
* [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown
2009-08-21 23:42 ` Thomas Gleixner
@ 2009-08-28 21:52 ` Pan, Jacob jun
2009-08-29 16:58 ` Thomas Gleixner
0 siblings, 1 reply; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:52 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Jeremy Fitzhardinge
>From 2de4f68e7b0403bb39954d7c2e3d5097d0e6e3ac Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Thu, 11 Jun 2009 20:34:47 -0700
Subject: [PATCH] x86/boot: adding hw subarch ID for Moorestown
x86 bootprotocol 2.07 has introduced hardware_subarch ID in the boot
parameters provided by FW. We use it to identify Moorestown platforms.
The subarchitecture ID will help select a set of platform features and
x86_quirks.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
Documentation/x86/boot.txt | 1 +
arch/x86/include/asm/bootparam.h | 11 +++++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index 8da3a79..30b43e1 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -599,6 +599,7 @@ Protocol: 2.07+
0x00000000 The default x86/PC environment
0x00000001 lguest
0x00000002 Xen
+ 0x00000003 Moorestown MID
Field name: hardware_subarch_data
Type: write (subarch-dependent)
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 1724e8d..631cae9 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -109,4 +109,15 @@ struct boot_params {
__u8 _pad9[276]; /* 0xeec */
} __attribute__((packed));
+#define N_X86_SUBARCHS 4
+
+enum {
+ X86_SUBARCH_PC = 0,
+ X86_SUBARCH_LGUEST,
+ X86_SUBARCH_XEN,
+ X86_SUBARCH_MRST,
+};
+
+
+
#endif /* _ASM_X86_BOOTPARAM_H */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 2/7] x86: introduce a set of platform feature flags
2009-08-21 22:36 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
@ 2009-08-28 21:52 ` Pan, Jacob jun
2009-08-28 21:52 ` [RFC PATCH 3/7] x86: add moorestown specific platform setup code Pan, Jacob jun
` (4 subsequent siblings)
6 siblings, 0 replies; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:52 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From 8c587b87eef49660b498dd3728dab73a254b7ea9 Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Thu, 11 Jun 2009 09:37:26 -0700
Subject: [PATCH] x86: introduce a set of platform feature flags
This patch introduces a set of x86 pc platform feature flags. the intention is
to clean up setup code based on the availability of patform features.
With the introduction of non-PC x86 platforms, these flags will also pave
the way for cleaner integration.
The current feature flags are not a complete set of all possible PC features
only the ones relavent to system setup, such as resource allocation, are
included.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
arch/x86/Kconfig | 13 +++-
arch/x86/include/asm/platform_feature.h | 68 +++++++++++++++++++
arch/x86/kernel/.gitignore | 1 +
arch/x86/kernel/Makefile | 11 +++
arch/x86/kernel/mkx86pcflags.pl | 32 +++++++++
arch/x86/kernel/platform_info.c | 112 +++++++++++++++++++++++++++++++
6 files changed, 236 insertions(+), 1 deletions(-)
create mode 100644 arch/x86/include/asm/platform_feature.h
create mode 100644 arch/x86/kernel/mkx86pcflags.pl
create mode 100644 arch/x86/kernel/platform_info.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 13ffa5d..7990f6c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1658,7 +1658,18 @@ config CMDLINE_OVERRIDE
This is used to work around broken boot loaders. This should
be set to 'N' under normal conditions.
-
+config MRST
+ bool "Moorestown MID platform"
+ default n
+ depends on X86_32
+ select SFI
+ help
+ Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
+ Internet Device(MID) platform. Moorestown consists of two chips:
+ Lincroft (CPU core, graphics, and memory controller) and Langwell IOH.
+ Unlike standard x86 PCs, Moorestown does not have many legacy devices
+ nor standard legacy replacement devices/features. e.g. Moorestown does
+ not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
endmenu
config ARCH_ENABLE_MEMORY_HOTPLUG
diff --git a/arch/x86/include/asm/platform_feature.h b/arch/x86/include/asm/platform_feature.h
new file mode 100644
index 0000000..fcf9907
--- /dev/null
+++ b/arch/x86/include/asm/platform_feature.h
@@ -0,0 +1,68 @@
+/*
+ * platform_feature.h - Defines x86 platform feature bits
+ *
+ * (C) Copyright 2008 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * 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; version 2
+ * of the License.
+ *
+ * Note: platform feature flags allow kernel to identify hardware capabilities
+ * at boottime and runtime. It enables binary compaitiblity between standard
+ * X86 PC and non-standard X86 platforms such as MID. These flags are default
+ * to X86 PC standard, at boot time, they will be overwritten by system tables
+ * provided by firmware.
+ *
+ */
+#ifndef _ASM_X86_PLATFORM_FEATURE_H
+#define _ASM_X86_PLATFORM_FEATURE_H
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+#include <asm/required-features.h>
+
+#define N_PLATFORM_CAPINTS 2 /* N 32-bit words worth of info */
+/* X86 base platform features, include PC, legacy free MID devices, etc.
+ * This list provides early and important information to the kernel in a
+ * centralized place such that kernel can make a decision on the best
+ * choice of which system devices to use. e.g. timers or interrupt
+ * controllers.
+ */
+#define X86_PLATFORM_FEATURE_8259 (0*32+0) /* i8259A PIC */
+#define X86_PLATFORM_FEATURE_8254 (0*32+1) /* i8253/4 PIT */
+#define X86_PLATFORM_FEATURE_IOAPIC (0*32+2) /* IO-APIC */
+#define X86_PLATFORM_FEATURE_HPET (0*32+3) /* HPET timer */
+#define X86_PLATFORM_FEATURE_RTC (0*32+4) /* real time clock*/
+#define X86_PLATFORM_FEATURE_FLOPPY (0*32+5) /* ISA floppy */
+#define X86_PLATFORM_FEATURE_ISA (0*32+6) /* ISA/LPC bus */
+#define X86_PLATFORM_FEATURE_BIOS (0*32+7) /* BIOS service,
+ * e.g. int calls
+ * EBDA, etc.
+ */
+#define X86_PLATFORM_FEATURE_ACPI (0*32+8) /* has ACPI support */
+#define X86_PLATFORM_FEATURE_SFI (0*32+9) /* has SFI support */
+#define X86_PLATFORM_FEATURE_8042 (0*32+10) /* i8042 KBC */
+#define X86_PLATFORM_FEATURE_APBT (0*32+11) /* APB timer */
+#define X86_PLATFORM_FEATURE_VRTC (0*32+12) /* virtual RTC */
+#define X86_PLATFORM_FEATURE_PCISHIM (0*32+13) /* fake PCI MCFG */
+
+extern __u32 platform_feature[N_PLATFORM_CAPINTS];
+extern const char *const
+ x86_platform_available_feature[N_PLATFORM_CAPINTS * 32];
+#define platform_has(bit) \
+ test_bit(bit, (unsigned long *)platform_feature)
+
+#define platform_feature_set_flag(bit) \
+ __set_bit(bit, (unsigned long *)platform_feature)
+
+#define clear_platform_feature(bit) \
+ __clear_bit(bit, (unsigned long *)platform_feature)
+
+void platform_feature_init_default(void);
+void clear_all_platform_feature(void);
+
+
+#endif /* _ASM_X86_PLATFORM_FEATURE_H */
diff --git a/arch/x86/kernel/.gitignore b/arch/x86/kernel/.gitignore
index 08f4fd7..0943d5e 100644
--- a/arch/x86/kernel/.gitignore
+++ b/arch/x86/kernel/.gitignore
@@ -1,3 +1,4 @@
vsyscall.lds
vsyscall_32.lds
vmlinux.lds
+x86pcflags.c
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 5929855..7aed450 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_IA32_EMULATION) += tls.o
obj-y += step.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += cpu/
+obj-y += platform_info.o x86pcflags.o
obj-y += acpi/
obj-y += reboot.o
obj-$(CONFIG_MCA) += mca_32.o
@@ -114,6 +115,16 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
+quiet_cmd_mkx86pcflags = MKFEATURE $@
+ cmd_mkx86pcflags = $(PERL) $(srctree)/$(src)/mkx86pcflags.pl $< $@
+
+platform_feature = $(src)/../include/asm/platform_feature.h
+
+
+targets += x86pcflags.c
+$(obj)/x86pcflags.c: $(platform_feature) $(src)/mkx86pcflags.pl FORCE
+ $(call if_changed,mkx86pcflags)
+
###
# 64 bit specific files
ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/mkx86pcflags.pl b/arch/x86/kernel/mkx86pcflags.pl
new file mode 100644
index 0000000..19c13aa
--- /dev/null
+++ b/arch/x86/kernel/mkx86pcflags.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+#
+# Generate the x86_platform_available_feature[] array from arch/x86/include/asm/platform_feature.h
+#
+
+($in, $out) = @ARGV;
+
+open(IN, "< $in\0") or die "$0: cannot open: $in: $!\n";
+open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n";
+
+print OUT "#include <asm/platform_feature.h>\n\n";
+print OUT "const char * const x86_platform_available_feature[N_PLATFORM_CAPINTS*32] = {\n";
+
+while (defined($line = <IN>)) {
+ if ($line =~ /^\s*\#\s*define\s+(X86_PLATFORM_FEATURE_(\S+))\s+(.*)$/) {
+ $macro = $1;
+ $feature = $2;
+ $tail = $3;
+ if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) {
+ $feature = $1;
+ }
+
+ if ($feature ne '') {
+ printf OUT "\t%-32s = \"%s\",\n",
+ "[$macro]", "\L$feature";
+ }
+ }
+}
+print OUT "};\n";
+
+close(IN);
+close(OUT);
diff --git a/arch/x86/kernel/platform_info.c b/arch/x86/kernel/platform_info.c
new file mode 100644
index 0000000..63cee8f
--- /dev/null
+++ b/arch/x86/kernel/platform_info.c
@@ -0,0 +1,112 @@
+#include <linux/smp.h>
+#include <linux/timex.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+
+#include <asm/bootparam.h>
+#include <asm/platform_feature.h>
+#include <asm/setup.h>
+#include <asm/bios_ebda.h>
+
+/*
+ * Set of default platform features of standard X86 PC. May be overwritten by
+ * information found during boot, such as boot parameters, SFI, ACPI tables,
+ * etc. Not every X86PC feature is listed here, only include useful ones that
+ * can not be safely detected at runtime.
+ */
+__u32 platform_feature[N_PLATFORM_CAPINTS] =
+{
+ (1UL << X86_PLATFORM_FEATURE_8259) |
+ (1UL << X86_PLATFORM_FEATURE_8042) |
+ (1UL << X86_PLATFORM_FEATURE_IOAPIC) |
+ (1UL << X86_PLATFORM_FEATURE_BIOS) |
+ (1UL << X86_PLATFORM_FEATURE_HPET) |
+ (1UL << X86_PLATFORM_FEATURE_8254) |
+ (1UL << X86_PLATFORM_FEATURE_RTC) |
+ (1UL << X86_PLATFORM_FEATURE_ISA) |
+ (1UL << X86_PLATFORM_FEATURE_FLOPPY),
+ 0
+};
+EXPORT_SYMBOL_GPL(platform_feature);
+
+inline void clear_all_platform_feature(void)
+{
+ memset(platform_feature, 0, sizeof(platform_feature));
+}
+
+static ssize_t
+sysfs_show_available_platform_feature(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *buf)
+{
+ ssize_t count = 0;
+ int i;
+
+ for (i = 0; i < 32*N_PLATFORM_CAPINTS; i++) {
+ if (x86_platform_available_feature[i] != NULL) {
+ count += snprintf(buf + count,
+ max((ssize_t)PAGE_SIZE - count,
+ (ssize_t)0), "%s ",
+ x86_platform_available_feature[i]);
+ }
+ }
+ count += snprintf(buf + count,
+ max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
+
+ return count;
+}
+
+static ssize_t
+sysfs_show_current_platform_feature(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ char *buf)
+{
+ ssize_t count = 0;
+ int i;
+
+ for (i = 0; i < 32*N_PLATFORM_CAPINTS; i++) {
+ if (platform_has(i))
+ count += snprintf(buf + count,
+ max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
+ "%s ", x86_platform_available_feature[i]);
+ }
+ count += snprintf(buf + count,
+ max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
+
+ return count;
+}
+
+static SYSDEV_ATTR(current_platform_feature, 0444,
+ sysfs_show_current_platform_feature,
+ NULL);
+
+static SYSDEV_ATTR(available_platform_feature, 0444,
+ sysfs_show_available_platform_feature, NULL);
+
+static struct sysdev_class platform_feature_sysclass = {
+ .name = "platform_feature",
+};
+
+static struct sys_device device_platform_feature = {
+ .id = 0,
+ .cls = &platform_feature_sysclass,
+};
+
+static int __init sysfs_platforminfo_init(void)
+{
+ int error = sysdev_class_register(&platform_feature_sysclass);
+
+ if (!error)
+ error = sysdev_register(&device_platform_feature);
+ if (!error)
+ error = sysdev_create_file(
+ &device_platform_feature,
+ &attr_current_platform_feature);
+ if (!error)
+ error = sysdev_create_file(
+ &device_platform_feature,
+ &attr_available_platform_feature);
+ return error;
+}
+arch_initcall(sysfs_platforminfo_init);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 3/7] x86: add moorestown specific platform setup code
2009-08-21 22:36 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
2009-08-28 21:52 ` [RFC PATCH 2/7] x86: introduce a set of platform feature flags Pan, Jacob jun
@ 2009-08-28 21:52 ` Pan, Jacob jun
2009-08-29 17:20 ` Thomas Gleixner
2009-08-28 21:53 ` [RFC PATCH 4/7] x86/apbt: Moorestown APB system timer driver Pan, Jacob jun
` (3 subsequent siblings)
6 siblings, 1 reply; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:52 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From dbb97928dc27061b56fc86b9b37f71f54bbafb59 Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Fri, 28 Aug 2009 08:31:45 -0700
Subject: [PATCH] x86: add moorestown specific platform setup code
This patch fills in platform_setup functions for Moorestown. The abstraction
is used to integarte into pc compaitible boot flow.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
arch/x86/include/asm/setup.h | 8 ++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/mrst.c | 149 ++++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/setup.c | 1 +
4 files changed, 159 insertions(+), 0 deletions(-)
create mode 100644 arch/x86/kernel/mrst.c
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 055b778..2ef1514 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -49,6 +49,14 @@ extern void reserve_standard_io_resources(void);
extern void i386_reserve_resources(void);
extern void setup_default_timer_irq(void);
+#ifdef CONFIG_MRST
+extern void mrst_early_detect(void);
+extern void setup_mrst_default_feature(void);
+#else
+static inline void mrst_early_detect(void) { }
+static inline void setup_mrst_default_feature(void) { };
+#endif
+
#ifndef _SETUP
/*
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 7aed450..4d0a9cd 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -105,6 +105,7 @@ obj-$(CONFIG_SCx200) += scx200.o
scx200-y += scx200_32.o
obj-$(CONFIG_OLPC) += olpc.o
+obj-$(CONFIG_MRST) += mrst.o
microcode-y := microcode_core.o
microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
new file mode 100644
index 0000000..671d8e5
--- /dev/null
+++ b/arch/x86/kernel/mrst.c
@@ -0,0 +1,149 @@
+/*
+ * mrst.c: Intel Moorestown platform specific setup code
+ *
+ * (C) Copyright 2008 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * 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; version 2
+ * of the License.
+ *
+ * Note:
+ *
+ */
+
+#include <linux/stackprotector.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/sfi.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/spi/langwell_pmic_gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+
+#include <asm/platform_feature.h>
+#include <asm/apb_timer.h>
+#include <asm/apic.h>
+#include <asm/hw_irq.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+
+#define LANGWELL_GPIO_ALT_ADDR 0xff12c038
+#define MRST_I2C_BUSNUM 3
+
+static inline void __init mrst_pre_intr_init(void)
+{
+ pre_init_apic_IRQ();
+}
+
+/*
+ * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
+ * APBT but cmdline option can also override it.
+ */
+static void __init mrst_setup_secondary_clock(void)
+{
+ if (disable_apbt_percpu)
+ return setup_secondary_APIC_clock();
+ else {
+#ifdef CONFIG_CC_STACKPROTECTOR
+ /*
+ * TBD:
+ * this is to avoid false stack corruption panic since
+ * request_irq will be called early for secondary apbt clock.
+ */
+ boot_init_stack_canary();
+#endif
+ apbt_setup_secondary_clock();
+ }
+}
+
+static void __init mrst_check_timer(void)
+{
+ if (timer_irq_works())
+ printk(KERN_INFO "APB timer works\n");
+ else
+ panic("Check APB timer failed\n");
+}
+
+static unsigned long __init mrst_calibrate_tsc(void)
+{
+ unsigned long flags, fast_calibrate;
+
+ local_irq_save(flags);
+ fast_calibrate = apbt_quick_calibrate();
+ local_irq_restore(flags);
+
+ if (fast_calibrate)
+ return fast_calibrate;
+
+ return 0;
+}
+
+static int mrst_pirq_enable_irq(struct pci_dev *dev)
+{
+ u8 pin;
+ struct io_apic_irq_attr irq_attr;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+ /* For platforms only have IOAPIC, the PCI irq line is 1:1 mapped to
+ * IOAPIC RTE entries, so we just enable RTE for the device.
+ */
+ irq_attr.ioapic = mp_sfi_find_ioapic(dev->irq);
+ irq_attr.ioapic_pin = dev->irq;
+ irq_attr.trigger = 1; /* level */
+ irq_attr.polarity = 1; /* active low */
+ io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
+
+ return 0;
+}
+
+
+inline void setup_mrst_default_feature(void)
+{
+ /*
+ * x86pc default platform setup ops are setup prior to start_kernel
+ * we override default platform_setup calls for Moorestown
+ */
+ platform_setup.resources.reserve_ebda_region = platform_setup_noop;
+ platform_setup.resources.probe_roms = platform_setup_noop;
+ platform_setup.resources.reserve_resources = platform_setup_noop;
+
+ platform_setup.irqs.pre_vector_init = mrst_pre_intr_init;
+ platform_setup.irqs.pci_enable_irq = mrst_pirq_enable_irq,
+
+ platform_setup.timers.timer_init = apbt_time_init;
+ platform_setup.timers.check_timers = mrst_check_timer;
+ platform_setup.timers.calibrate_tsc = mrst_calibrate_tsc;
+
+ platform_cpuhotplug_setup.setup_percpu_clockev =
+ mrst_setup_secondary_clock;
+
+
+ /* assign feature flags */
+ clear_all_platform_feature();
+ platform_feature_set_flag(X86_PLATFORM_FEATURE_SFI);
+ platform_feature_set_flag(X86_PLATFORM_FEATURE_IOAPIC);
+ platform_feature_set_flag(X86_PLATFORM_FEATURE_APBT);
+ platform_feature_set_flag(X86_PLATFORM_FEATURE_VRTC);
+ platform_feature_set_flag(X86_PLATFORM_FEATURE_PCISHIM);
+
+}
+
+void __init mrst_early_detect(void)
+{
+ int subarch_id = boot_params.hdr.hardware_subarch;
+
+ if ((subarch_id >= 0) && (subarch_id < N_X86_SUBARCHS)) {
+ if (subarch_id == X86_SUBARCH_MRST) {
+ setup_mrst_default_feature();
+ return;
+ }
+ } else {
+ printk(KERN_INFO "Use default X86 platform feature set\n");
+ }
+}
+
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 35c3edc..9fef9d9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -692,6 +692,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_X86_32
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
visws_early_detect();
+ mrst_early_detect();
#else
printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 4/7] x86/apbt: Moorestown APB system timer driver
2009-08-21 22:36 ` Thomas Gleixner
` (2 preceding siblings ...)
2009-08-28 21:52 ` [RFC PATCH 3/7] x86: add moorestown specific platform setup code Pan, Jacob jun
@ 2009-08-28 21:53 ` Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 5/7] x86/apic: decouple legacy irq handling in ioapic Pan, Jacob jun
` (2 subsequent siblings)
6 siblings, 0 replies; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:53 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From c6e346613ce50ab24b0d23ab6ff780790080a195 Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Wed, 15 Jul 2009 14:12:55 -0700
Subject: [PATCH] x86/apbt: Moorestown APB system timer driver
Moorestown platform has introduced legacy replacement system timers, called
APB timers. There are four timers available to the kernel via SFI MTMR table.
APB timers are always running and have a known frequency. Two timers used
for per CPU clockevent deivces, one for clocksource, one by the watchdog
driver.
This driver serve similar functionality found in i8254 and HPET,
APB timers are given higher rating than local APIC timer so that they are
used for per CPU timer in SMP/HT. Broadcast timer is avoided. If cmdline
option no_percpu_apbt is given, the kernel will pick local APIC timers
and one APB timer as broadcast clockevent device.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
Documentation/kernel-parameters.txt | 4 +
arch/x86/Kconfig | 11 +
arch/x86/include/asm/apb_timer.h | 67 +++
arch/x86/kernel/Makefile | 2 +-
arch/x86/kernel/apb_timer.c | 762 +++++++++++++++++++++++++++++++++++
arch/x86/kernel/apic/apic.c | 3 +
6 files changed, 848 insertions(+), 1 deletions(-)
create mode 100644 arch/x86/include/asm/apb_timer.h
create mode 100644 arch/x86/kernel/apb_timer.c
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 2b79f24..a58cbf6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1654,6 +1654,10 @@ and is between 256 and 4096 characters. It is defined in the file
nomfgpt [X86-32] Disable Multi-Function General Purpose
Timer usage (for AMD Geode machines).
+ no_percpu_apbt [X86-32,APBT]
+ Disable per CPU APB timer as clockevent devices. this
+ will make the local APIC timer used as per CPU timer.
+
norandmaps Don't use address space randomization. Equivalent to
echo 0 > /proc/sys/kernel/randomize_va_space
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 95de8c0..6fa83a6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -571,6 +571,16 @@ config HPET_EMULATE_RTC
def_bool y
depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
+config APB_TIMER
+ def_bool y if MRST
+ prompt "Langwell APB Timer Support" if MRST
+ help
+ APB timer is the replacement for 8254, HPET on X86 MID platforms.
+ The APBT provides a stable time base on SMP
+ systems, unlike the TSC, but it is more expensive to access,
+ as it is off-chip. APB timers are always running regardless of CPU
+ C states, they are used as per CPU clockevent device when possible.
+
# Mark as embedded because too many people got it wrong.
# The code disables itself when not needed.
config DMI
@@ -1663,6 +1673,7 @@ config MRST
default n
depends on X86_32
select SFI
+ select APB_TIMER
help
Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
Internet Device(MID) platform. Moorestown consists of two chips:
diff --git a/arch/x86/include/asm/apb_timer.h b/arch/x86/include/asm/apb_timer.h
new file mode 100644
index 0000000..9a8596b
--- /dev/null
+++ b/arch/x86/include/asm/apb_timer.h
@@ -0,0 +1,67 @@
+/*
+ * apb_timer.h: Driver for Langwell APB timer based on Synopsis DesignWare
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * 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; version 2
+ * of the License.
+ *
+ * Note:
+ */
+
+#ifndef ASM_X86_APBT_H
+#define ASM_X86_APBT_H
+#include <linux/sfi.h>
+
+#ifdef CONFIG_APB_TIMER
+
+/* Langwell DW APB timer registers */
+#define APBTMR_N_LOAD_COUNT 0x00
+#define APBTMR_N_CURRENT_VALUE 0x04
+#define APBTMR_N_CONTROL 0x08
+#define APBTMR_N_EOI 0x0c
+#define APBTMR_N_INT_STATUS 0x10
+
+#define APBTMRS_INT_STATUS 0xa0
+#define APBTMRS_EOI 0xa4
+#define APBTMRS_RAW_INT_STATUS 0xa8
+#define APBTMRS_COMP_VERSION 0xac
+#define APBTMRS_REG_SIZE 0x14
+
+/* register bits */
+#define APBTMR_CONTROL_ENABLE (1<<0)
+#define APBTMR_CONTROL_MODE_PERIODIC (1<<1) /*1: periodic 0:free running */
+#define APBTMR_CONTROL_INT (1<<2)
+
+/* default memory mapped register base */
+#define LNW_SCU_ADDR 0xFF100000
+#define LNW_EXT_TIMER_OFFSET 0x1B800
+#define APBT_DEFAULT_BASE (LNW_SCU_ADDR+LNW_EXT_TIMER_OFFSET)
+#define LNW_EXT_TIMER_PGOFFSET 0x800
+
+/* APBT clock speed range from PCLK to fabric base, 25-100MHz */
+#define APBT_MAX_FREQ 50
+#define APBT_MIN_FREQ 1
+#define APBT_MMAP_SIZE 1024
+
+#define APBT_DEV_USED 1
+
+extern void apbt_time_init(void);
+extern struct clock_event_device *global_clock_event;
+extern struct sfi_mtimer_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
+extern unsigned long apbt_quick_calibrate(void);
+extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
+extern void apbt_setup_secondary_clock(void);
+extern unsigned int boot_cpu_id;
+extern int disable_apbt_percpu;
+
+#else /* CONFIG_APB_TIMER */
+
+static inline unsigned long apbt_quick_calibrate(void) {return 0; }
+static inline void apbt_time_init(void) {return 0; }
+
+#endif
+#endif /* ASM_X86_APBT_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index f23811d..d1dcfb7 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -87,7 +87,7 @@ obj-$(CONFIG_VM86) += vm86_32.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
-
+obj-$(CONFIG_APB_TIMER) += apb_timer.o
obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
new file mode 100644
index 0000000..ad454ec
--- /dev/null
+++ b/arch/x86/kernel/apb_timer.c
@@ -0,0 +1,762 @@
+/*
+ * apb_timer.c: Driver for Langwell APB timers
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * 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; version 2
+ * of the License.
+ *
+ * Note:
+ * Langwell is the south complex of Intel Moorestown MID platform. There are
+ * eight external timers in total that can be used by the operating system.
+ * The timer information, such as frequency and addresses, is provided to the
+ * OS via SFI tables.
+ * Timer interrupts are routed via FW/HW emulated IOAPIC independently via
+ * individual redirection table entries (RTE).
+ * Unlike HPET, there is no master counter, therefore one of the timers are
+ * used as clocksource. The overall allocation looks like:
+ * - timer 0 - NR_CPUs for per cpu timer
+ * - one timer for clocksource
+ * - one timer for watchdog driver.
+ * It is also worth notice that APB timer does not support true one-shot mode,
+ * free-running mode will be used here to emulate one-shot mode.
+ * APB timer can also be used as broadcast timer along with per cpu local APIC
+ * timer, but by default APB timer has higher rating than local APIC timers.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/sfi.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/irq.h>
+
+#include <asm/fixmap.h>
+#include <asm/apb_timer.h>
+
+#define APBT_MASK CLOCKSOURCE_MASK(32)
+#define APBT_SHIFT 22
+#define APBT_CLOCKEVENT_RATING 150
+#define APBT_CLOCKSOURCE_RATING 250
+#define APBT_MIN_DELTA_USEC 200
+
+#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
+#define APBT_CLOCKEVENT0_NUM (0)
+#define APBT_CLOCKEVENT1_NUM (1)
+#define APBT_CLOCKSOURCE_NUM (2)
+
+static unsigned long apbt_address;
+static int apb_timer_block_enabled;
+static void __iomem *apbt_virt_address;
+static int phy_cs_timer_id;
+
+/*
+ * Common DW APB timer info
+ */
+static uint64_t apbt_freq;
+
+static void apbt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt);
+static int apbt_next_event(unsigned long delta,
+ struct clock_event_device *evt);
+static cycle_t apbt_read_clocksource(struct clocksource *cs);
+static void apbt_restart_clocksource(void);
+
+struct apbt_dev {
+ struct clock_event_device evt;
+ unsigned int num;
+ int cpu;
+ unsigned int irq;
+ unsigned int tick;
+ unsigned int count;
+ unsigned int flags;
+ char name[10];
+};
+
+int disable_apbt_percpu __cpuinitdata;
+
+#ifdef CONFIG_SMP
+static unsigned int apbt_num_timers_used;
+static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
+static struct apbt_dev *apbt_devs;
+#endif
+
+static inline unsigned long apbt_readl_reg(unsigned long a)
+{
+ return readl(apbt_virt_address + a);
+}
+
+static inline void apbt_writel_reg(unsigned long d, unsigned long a)
+{
+ writel(d, apbt_virt_address + a);
+}
+
+static inline unsigned long apbt_readl(int n, unsigned long a)
+{
+ return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_writel(int n, unsigned long d, unsigned long a)
+{
+ writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_set_mapping(void)
+{
+ struct sfi_mtimer_entry *mtmr;
+
+ if (apbt_virt_address) {
+ pr_debug("APBT base already mapped\n");
+ return;
+ }
+ mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+ if (mtmr == NULL) {
+ printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+ APBT_CLOCKEVENT0_NUM);
+ return;
+ }
+ apbt_address = (unsigned long)mtmr->phy_addr;
+ if (!apbt_address) {
+ printk(KERN_WARNING "No timer base from SFI, use default\n");
+ apbt_address = APBT_DEFAULT_BASE;
+ }
+ apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
+ if (apbt_virt_address) {
+ pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\
+ (void *)apbt_address, (void *)apbt_virt_address);
+ } else {
+ pr_debug("Failed mapping APBT phy address at %p\n",\
+ (void *)apbt_address);
+ goto panic_noapbt;
+ }
+ apbt_freq = mtmr->freq / USEC_PER_SEC;
+ sfi_free_mtmr(mtmr);
+
+ /* Now figure out the physical timer id for clocksource device */
+ mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
+ if (mtmr == NULL)
+ goto panic_noapbt;
+
+ /* Now figure out the physical timer id */
+ phy_cs_timer_id = (unsigned int)(mtmr->phy_addr & 0xff)
+ / APBTMRS_REG_SIZE;
+ pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id);
+ return;
+
+panic_noapbt:
+ panic("Failed to setup APB system timer\n");
+
+}
+
+static inline void apbt_clear_mapping(void)
+{
+ iounmap(apbt_virt_address);
+ apbt_virt_address = NULL;
+}
+
+/*
+ * APBT timer interrupt enable / disable
+ */
+static inline int is_apbt_capable(void)
+{
+ return apbt_virt_address ? 1 : 0;
+}
+
+static struct clocksource clocksource_apbt = {
+ .name = "apbt",
+ .rating = APBT_CLOCKSOURCE_RATING,
+ .read = apbt_read_clocksource,
+ .mask = APBT_MASK,
+ .shift = APBT_SHIFT,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .resume = apbt_restart_clocksource,
+};
+
+/* boot APB clock event device */
+static struct clock_event_device apbt_clockevent = {
+ .name = "apbt0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = apbt_set_mode,
+ .set_next_event = apbt_next_event,
+ .shift = APBT_SHIFT,
+ .irq = 0,
+ .rating = APBT_CLOCKEVENT_RATING,
+};
+
+/*
+ * if user does not want to use per CPU apb timer, just give it a lower rating
+ * than local apic timer and skip the late per cpu timer init.
+ */
+static inline int __init setup_no_percpu_apbt(char *arg)
+{
+ disable_apbt_percpu = 1;
+ return 0;
+}
+__setup("no_percpu_apbt", setup_no_percpu_apbt);
+
+/*
+ * start count down from 0xffff_ffff. this is done by toggling the enable bit
+ * then load initial load count to ~0.
+ */
+static void apbt_start_counter(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
+ /* enable, mask interrupt */
+ ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+ ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ /* read it once to get cached counter value initialized */
+ apbt_read_clocksource(&clocksource_apbt);
+}
+
+#ifdef CONFIG_SMP
+static irqreturn_t apbt_interrupt_handler(int irq, void *data)
+{
+ struct apbt_dev *dev = (struct apbt_dev *)data;
+ struct clock_event_device *aevt = &dev->evt;
+
+ if (!aevt->event_handler) {
+ printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
+ dev->num);
+ return IRQ_NONE;
+ }
+ aevt->event_handler(aevt);
+ return IRQ_HANDLED;
+}
+#endif
+
+static void apbt_restart_clocksource(void)
+{
+ apbt_start_counter(phy_cs_timer_id);
+}
+
+/* Setup IRQ routing via IOAPIC */
+#ifdef CONFIG_SMP
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+ struct irq_chip *chip;
+
+ /* timer0 irq has been setup early */
+ if (adev->irq == 0)
+ return;
+ chip = get_irq_chip(adev->irq);
+ disable_irq(adev->irq);
+ irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
+ /* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
+ set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
+ enable_irq(adev->irq);
+ if (system_state == SYSTEM_BOOTING)
+ if (request_irq(adev->irq, apbt_interrupt_handler,
+ IRQF_DISABLED|IRQF_NOBALANCING, adev->name, adev)) {
+ printk(KERN_ERR "Failed request IRQ for APBT%d\n", adev->num);
+ }
+}
+#endif
+
+static void apbt_enable_int(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+ /* clear pending intr */
+ apbt_readl(n, APBTMR_N_EOI);
+ ctrl &= ~APBTMR_CONTROL_INT;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+static void apbt_disable_int(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+ ctrl &= ~APBTMR_CONTROL_INT;
+ ctrl |= APBTMR_CONTROL_INT;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+
+static int apbt_clockevent_register(void)
+{
+ struct sfi_mtimer_entry *mtmr;
+
+ mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+ if (mtmr == NULL) {
+ printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+ APBT_CLOCKEVENT0_NUM);
+ return -ENODEV;
+ }
+
+ /*
+ * We need to calculate the scaled math multiplication factor for
+ * nanosecond to apbt tick conversion.
+ * mult = (nsec/cycle)*2^APBT_SHIFT
+ */
+ apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq
+ , NSEC_PER_SEC, APBT_SHIFT);
+
+ /* Calculate the min / max delta */
+ apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
+ &apbt_clockevent);
+ apbt_clockevent.min_delta_ns = clockevent_delta2ns(
+ APBT_MIN_DELTA_USEC*apbt_freq,
+ &apbt_clockevent);
+ /*
+ * Start apbt with the boot cpu mask and make it
+ * global if not used for per cpu timer.
+ */
+ apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
+
+ if (disable_apbt_percpu) {
+ apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
+ global_clock_event = &apbt_clockevent;
+ printk(KERN_DEBUG "%s clockevent registered as global\n",
+ global_clock_event->name);
+ }
+ if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler,
+ IRQF_DISABLED|IRQF_NOBALANCING,
+ apbt_clockevent.name, &apbt_clockevent)) {
+ printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+ apbt_clockevent.irq);
+ }
+
+ clockevents_register_device(&apbt_clockevent);
+ /* Start APBT 0 interrupts */
+ apbt_enable_int(APBT_CLOCKEVENT0_NUM);
+
+ sfi_free_mtmr(mtmr);
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+/* Should be called with per cpu */
+static int apbt_clockevent_late_register(void)
+{
+ struct apbt_dev *adev;
+ struct clock_event_device *aevt;
+ int cpu;
+
+ /* Don't register boot CPU clockevent */
+ cpu = smp_processor_id();
+ if (cpu == boot_cpu_id)
+ return 0;
+ /*
+ * We need to calculate the scaled math multiplication factor for
+ * nanosecond to apbt tick conversion.
+ * mult = (nsec/cycle)*2^APBT_SHIFT
+ */
+ printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
+ adev = &per_cpu(cpu_apbt_dev, cpu);
+ aevt = &adev->evt;
+
+ memcpy(aevt, &apbt_clockevent, sizeof(*aevt));
+ aevt->cpumask = cpumask_of(cpu);
+ aevt->name = adev->name;
+ aevt->mode = CLOCK_EVT_MODE_UNUSED;
+
+ printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n",
+ cpu, aevt->name, *(u32 *)aevt->cpumask);
+
+ apbt_setup_irq(adev);
+
+ clockevents_register_device(aevt);
+
+ apbt_enable_int(cpu);
+
+ return 0;
+}
+
+/* Initialize per CPU timer data structures based on SFI MTMR table */
+static int apbt_cpuhp_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ unsigned long cpu = (unsigned long)hcpu;
+ struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
+
+ switch (action & 0xf) {
+ case CPU_DEAD:
+ if (system_state == SYSTEM_RUNNING)
+ pr_debug("skipping APBT CPU %lu offline\n", cpu);
+ else if (adev) {
+ pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
+ apbt_disable_int(cpu);
+ free_irq(adev->irq, adev);
+ }
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static __init int apbt_late_init(void)
+{
+ if (disable_apbt_percpu)
+ return 0;
+ /* This notifier should be called after workqueue is ready */
+ hotcpu_notifier(apbt_cpuhp_notify, -20);
+ return 0;
+}
+fs_initcall(apbt_late_init);
+
+inline void apbt_setup_secondary_clock(void)
+{
+
+ apbt_clockevent_late_register();
+}
+
+#endif
+
+static void apbt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl;
+ uint64_t delta;
+ int timer_num;
+ struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+ timer_num = adev->num;
+
+ if ((timer_num < 0) || (timer_num > sfi_mtimer_num)) {
+ printk(KERN_ERR "apbt: set mode for invalid timer %d\n",
+ timer_num);
+ return;
+ }
+ pr_debug("%s CPU %d timer %d mode=%d\n",
+ __func__, first_cpu(*evt->cpumask), timer_num, mode);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
+ delta >>= apbt_clockevent.shift;
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /*
+ * DW APB p. 46, have to disable timer before load counter,
+ * may cause sync problem.
+ */
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ udelay(1);
+ pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
+ apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+ /* APB timer does not have one-shot mode, use free running mode */
+ case CLOCK_EVT_MODE_ONESHOT:
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ /*
+ * set free running mode, this mode will let timer reload max
+ * timeout which will give time (3min on 25MHz clock) to rearm
+ * the next event, therefore emulate the one-shot mode.
+ */
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /* write again to set free running mode */
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+
+ /*
+ * DW APB p. 46, load counter with all 1s before starting free
+ * running mode.
+ */
+ apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ apbt_enable_int(timer_num);
+ break;
+ }
+}
+
+static int apbt_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl;
+ int timer_num;
+
+ struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+ timer_num = adev->num;
+ /* Disable timer */
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /* write new count */
+ apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ return 0;
+}
+
+/*
+ * APB timer clock is not in sync with pclk on Langwell, which translates to
+ * unreliable read value caused by sampling error. the error does not add up
+ * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
+ * would go backwards. the following code is trying to prevent time traveling
+ * backwards. little bit paranoid.
+ */
+static cycle_t apbt_read_clocksource(struct clocksource *cs)
+{
+ unsigned long t0, t1, t2;
+ static unsigned long last_read;
+
+bad_count:
+ t1 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ t2 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ if (unlikely(t1 < t2)) {
+ pr_debug("APBT: read current count error %lx:%lx:%lx\n",
+ t1, t2, t2 - t1);
+ goto bad_count;
+ }
+ /*
+ * check against cached last read, makes sure time does not go back.
+ * it could be a normal rollover but we will do tripple check anyway
+ */
+ if (unlikely(t2 > last_read)) {
+ /* check if we have a normal rollover */
+ unsigned long raw_intr_status =
+ apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
+ /*
+ * cs timer interrupt is masked but raw intr bit is set if
+ * rollover occurs. then we read EOI reg to clear it.
+ */
+ if (raw_intr_status & (1 << phy_cs_timer_id)) {
+ apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
+ goto out;
+ }
+ pr_debug("APB CS going back %lx:%lx:%lx ",
+ t2, last_read, t2 - last_read);
+bad_count_x3:
+ pr_debug(KERN_INFO "tripple check enforced\n");
+ t0 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ udelay(1);
+ t1 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ udelay(1);
+ t2 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ if ((t2 > t1) || (t1 > t0)) {
+ printk(KERN_ERR "Error: APB CS tripple check failed\n");
+ goto bad_count_x3;
+ }
+ }
+out:
+ last_read = t2;
+ return (cycle_t)~t2;
+}
+
+static int apbt_clocksource_register(void)
+{
+ u64 start, now;
+ cycle_t t1;
+
+ /* Start the counter, use timer 2 as source, timer 0/1 for event */
+ apbt_start_counter(phy_cs_timer_id);
+
+ /* Verify whether apbt counter works */
+ t1 = apbt_read_clocksource(&clocksource_apbt);
+ rdtscll(start);
+
+ /*
+ * We don't know the TSC frequency yet, but waiting for
+ * 200000 TSC cycles is safe:
+ * 4 GHz == 50us
+ * 1 GHz == 200us
+ */
+ do {
+ rep_nop();
+ rdtscll(now);
+ } while ((now - start) < 200000UL);
+
+ /* APBT is the only always on clocksource, it has to work! */
+ if (t1 == apbt_read_clocksource(&clocksource_apbt))
+ panic("APBT counter not counting. APBT disabled\n");
+
+ /*
+ * initialize and register APBT clocksource
+ * convert that to ns/clock cycle
+ * mult = (ns/c) * 2^APBT_SHIFT
+ */
+ clocksource_apbt.mult = div_sc(MSEC_PER_SEC,
+ (unsigned long) apbt_freq, APBT_SHIFT);
+ clocksource_register(&clocksource_apbt);
+
+ return 0;
+}
+
+/*
+ * Early setup the APBT timer, only use timer 0 for booting then switch to
+ * per CPU timer if possible.
+ * returns 1 if per cpu apbt is setup
+ * returns 0 if no per cpu apbt is chosen
+ * panic if set up failed, this is the only platform timer on Moorestown.
+ */
+void __init apbt_time_init(void)
+{
+#ifdef CONFIG_SMP
+ int i;
+ struct sfi_mtimer_entry *p_mtmr;
+ unsigned int percpu_timer;
+ struct apbt_dev *adev;
+#endif
+
+ if (apb_timer_block_enabled)
+ return;
+ apbt_set_mapping();
+ if (apbt_virt_address) {
+ pr_debug("Found APBT version 0x%lx\n",\
+ apbt_readl_reg(APBTMRS_COMP_VERSION));
+ } else
+ goto out_noapbt;
+ /*
+ * Read the frequency and check for a sane value, for ESL model
+ * we extend the possible clock range to allow time scaling.
+ */
+
+ if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
+ pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq);
+ goto out_noapbt;
+ }
+ if (apbt_clocksource_register()) {
+ pr_debug("APBT has failed to register clocksource\n");
+ goto out_noapbt;
+ }
+ if (!apbt_clockevent_register())
+ apb_timer_block_enabled = 1;
+ else {
+ pr_debug("APBT has failed to register clockevent\n");
+ goto out_noapbt;
+ }
+#ifdef CONFIG_SMP
+ /* kernel cmdline disable apb timer, so we will use lapic timers */
+ if (disable_apbt_percpu) {
+ printk(KERN_INFO "apbt: disabled per cpu timer\n");
+ return;
+ }
+ pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
+ if (num_possible_cpus() <= 2 &&
+ num_possible_cpus() <= sfi_mtimer_num) {
+ percpu_timer = 1;
+ apbt_num_timers_used = num_possible_cpus();
+ } else {
+ percpu_timer = 0;
+ apbt_num_timers_used = 1;
+ adev = &per_cpu(cpu_apbt_dev, 0);
+ adev->flags &= ~APBT_DEV_USED;
+ }
+ pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
+
+ /* here we set up per CPU timer data structure */
+ apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
+ GFP_KERNEL);
+ if (!apbt_devs) {
+ printk(KERN_ERR "Failed to allocate APB timer devices\n");
+ return;
+ }
+ for (i = 0; i < apbt_num_timers_used; i++) {
+ adev = &per_cpu(cpu_apbt_dev, i);
+ adev->num = i;
+ adev->cpu = i;
+ p_mtmr = sfi_get_mtmr(i);
+ if (p_mtmr) {
+ adev->tick = p_mtmr->freq;
+ adev->irq = p_mtmr->irq;
+ } else
+ printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
+ adev->count = 0;
+ sprintf(adev->name, "apbt%d", i);
+ }
+#endif
+
+ return;
+
+out_noapbt:
+ apbt_clear_mapping();
+ apb_timer_block_enabled = 0;
+ panic("failed to enable APB timer\n");
+}
+
+static inline void apbt_disable(int n)
+{
+ if (is_apbt_capable()) {
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ }
+}
+
+/* called before apb_timer_enable, use early map */
+unsigned long apbt_quick_calibrate()
+{
+ int i, scale;
+ u64 old, new;
+ cycle_t t1, t2;
+ unsigned long khz = 0;
+ u32 loop, shift;
+
+ apbt_set_mapping();
+ apbt_start_counter(phy_cs_timer_id);
+
+ /* check if the timer can count down, otherwise return */
+ old = apbt_read_clocksource(&clocksource_apbt);
+ i = 10000;
+ while (--i) {
+ if (old != apbt_read_clocksource(&clocksource_apbt))
+ break;
+ }
+ if (!i)
+ goto failed;
+
+ /* count 16 ms */
+ loop = (apbt_freq * 1000) << 4;
+
+ /* restart the timer to ensure it won't get to 0 in the calibration */
+ apbt_start_counter(phy_cs_timer_id);
+
+ old = apbt_read_clocksource(&clocksource_apbt);
+ old += loop;
+
+ t1 = __native_read_tsc();
+
+ do {
+ new = apbt_read_clocksource(&clocksource_apbt);
+ } while (new < old);
+
+ t2 = __native_read_tsc();
+
+ shift = 5;
+ if (unlikely(loop >> shift == 0)) {
+ printk(KERN_INFO
+ "APBT TSC calibration failed, not enough resolution\n");
+ return 0;
+ }
+ scale = (int)div_u64((t2 - t1), loop >> shift);
+ khz = (scale * apbt_freq * 1000) >> shift;
+ printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
+ return khz;
+failed:
+ return 0;
+}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index c4eabd4..4503767 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -738,6 +738,9 @@ static int __init calibrate_APIC_clock(void)
*/
void __init setup_boot_APIC_clock(void)
{
+ /* we rely on global clockevent for calibration */
+ if (global_clock_event == NULL)
+ return;
/*
* The local apic timer can be disabled via the kernel
* commandline or from the CPU detection code. Register the lapic
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 5/7] x86/apic: decouple legacy irq handling in ioapic
2009-08-21 22:36 ` Thomas Gleixner
` (3 preceding siblings ...)
2009-08-28 21:53 ` [RFC PATCH 4/7] x86/apbt: Moorestown APB system timer driver Pan, Jacob jun
@ 2009-08-28 21:53 ` Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 6/7] x86/apic: Early setup IOAPIC for APB timer Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 7/7] x86: add more platform_setup functions Pan, Jacob jun
6 siblings, 0 replies; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:53 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From b37e4a846402d0ef7b1c19ea17d2d3aee22e81c2 Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Wed, 15 Jul 2009 11:29:42 -0700
Subject: [PATCH] x86/apic: RFC decouple legacy irq handling in ioapic
This patch uses platform feature flags to separate i8259/PIC from ioapic.
A cleaner solution might be adding abstraction for device interrupt
controller and moving apic initialization earlier so that
platforms with legacy replace devices can boot without the constriant of
PIC, PIT, etc. Such change obviously introduces risk.
The intention of this patch is also to show what kind of changes are needed
for non-pc x86 platform such as Moorestown MID. perhpas we can take a phased
approach.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
arch/x86/kernel/apic/io_apic.c | 31 ++++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a22b710..ccc746f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -62,7 +62,7 @@
#include <asm/hw_irq.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_irq.h>
-
+#include <asm/platform_feature.h>
#include <asm/apic.h>
#define __apicdebuginit(type) static type __init
@@ -1447,6 +1447,12 @@ int setup_ioapic_entry(int apic_id, int irq,
return 0;
}
+static inline int is_i8259_legacy_irq(int irq)
+{
+ return ((irq < NR_IRQS_LEGACY)
+ && platform_has(X86_PLATFORM_FEATURE_8259));
+}
+
static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
int trigger, int polarity)
{
@@ -1480,7 +1486,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
}
ioapic_register_intr(irq, desc, trigger);
- if (irq < NR_IRQS_LEGACY)
+ if (is_i8259_legacy_irq(irq))
disable_8259A_irq(irq);
ioapic_write_entry(apic_id, pin, entry);
@@ -1851,6 +1857,9 @@ __apicdebuginit(void) print_PIC(void)
unsigned int v;
unsigned long flags;
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
+
if (apic_verbosity == APIC_QUIET)
return;
@@ -1914,6 +1923,8 @@ void __init enable_IO_APIC(void)
spin_unlock_irqrestore(&ioapic_lock, flags);
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
}
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
for(apic = 0; apic < nr_ioapics; apic++) {
int pin;
/* See if any of the pins is in ExtINT mode */
@@ -1968,6 +1979,8 @@ void disable_IO_APIC(void)
*/
clear_IO_APIC();
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
/*
* If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
@@ -2198,7 +2211,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
struct irq_cfg *cfg;
spin_lock_irqsave(&ioapic_lock, flags);
- if (irq < NR_IRQS_LEGACY) {
+ if (is_i8259_legacy_irq(irq)) {
disable_8259A_irq(irq);
if (i8259A_irq_pending(irq))
was_pending = 1;
@@ -2709,7 +2722,7 @@ static inline void init_IO_APIC_traps(void)
* so default to an old-fashioned 8259
* interrupt if we can..
*/
- if (irq < NR_IRQS_LEGACY)
+ if (is_i8259_legacy_irq(irq))
make_8259A_irq(irq);
else
/* Strange. Oh, well.. */
@@ -3052,9 +3065,13 @@ void __init setup_IO_APIC(void)
/*
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
+ * For platforms that do not have legacy IRQs, IOAPIC IRQ can be any
+ * number.
*/
-
- io_apic_irqs = ~PIC_IRQS;
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ io_apic_irqs = ~0;
+ else
+ io_apic_irqs = ~PIC_IRQS;
apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
/*
@@ -3907,7 +3924,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
/*
* IRQs < 16 are already in the irq_2_pin[] map
*/
- if (irq >= NR_IRQS_LEGACY) {
+ if (!is_i8259_legacy_irq(irq)) {
cfg = desc->chip_data;
add_pin_to_irq_node(cfg, node, ioapic, pin);
}
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 6/7] x86/apic: Early setup IOAPIC for APB timer
2009-08-21 22:36 ` Thomas Gleixner
` (4 preceding siblings ...)
2009-08-28 21:53 ` [RFC PATCH 5/7] x86/apic: decouple legacy irq handling in ioapic Pan, Jacob jun
@ 2009-08-28 21:53 ` Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 7/7] x86: add more platform_setup functions Pan, Jacob jun
6 siblings, 0 replies; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:53 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From 9438ac713c0175e975ef3d0013e6bf2b46883dd0 Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Wed, 15 Jul 2009 11:30:40 -0700
Subject: [PATCH] x86/apic: Early setup IOAPIC for APB timer
Intel Moorestown platform uses APB system timers which rely
on IOAPIC to deliver its interrupts. Early setup the APIC
system is necessary to allow timer interrupts.
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
arch/x86/include/asm/apic.h | 1 +
arch/x86/kernel/apic/io_apic.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 8b542f4..4f2d26d 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -84,6 +84,7 @@ extern void xapic_wait_icr_idle(void);
extern u32 safe_xapic_wait_icr_idle(void);
extern void xapic_icr_write(u32, u32);
extern int setup_profiling_timer(unsigned int);
+extern void pre_init_apic_IRQ(void);
static inline void native_apic_mem_write(u32 reg, u32 v)
{
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index ccc746f..25a5b72 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -36,6 +36,7 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/jiffies.h> /* time_after() */
+#include <linux/sfi.h>
#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
#endif
@@ -63,6 +64,7 @@
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_irq.h>
#include <asm/platform_feature.h>
+#include <asm/apb_timer.h>
#include <asm/apic.h>
#define __apicdebuginit(type) static type __init
@@ -4211,3 +4213,18 @@ void __init ioapic_insert_resources(void)
r++;
}
}
+
+/* Enable IOAPIC early just for system timer */
+void __init pre_init_apic_IRQ(void)
+{
+ struct irq_cfg *cfg;
+
+ printk(KERN_INFO "Early APIC setup for system timer\n");
+#ifndef CONFIG_SMP
+ phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+#endif
+ setup_local_APIC();
+ cfg = irq_cfg(0);
+ add_pin_to_irq_node(cfg, 0, 0, 0);
+ setup_timer_IRQ0_pin(0, 0, cfg->vector);
+}
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* [RFC PATCH 7/7] x86: add more platform_setup functions
2009-08-21 22:36 ` Thomas Gleixner
` (5 preceding siblings ...)
2009-08-28 21:53 ` [RFC PATCH 6/7] x86/apic: Early setup IOAPIC for APB timer Pan, Jacob jun
@ 2009-08-28 21:53 ` Pan, Jacob jun
2009-08-29 17:31 ` Thomas Gleixner
6 siblings, 1 reply; 53+ messages in thread
From: Pan, Jacob jun @ 2009-08-28 21:53 UTC (permalink / raw)
To: Thomas Gleixner, Jeremy Fitzhardinge
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria
>From fbfe65d64e4dbb31940d31a59e080bfa15d121bb Mon Sep 17 00:00:00 2001
From: Jacob Pan <jacob.jun.pan@intel.com>
Date: Wed, 8 Jul 2009 16:51:42 -0700
Subject: [PATCH] x86: RFC add more platform_setup functions
check_timer can be abstracted so that we don't have to do the complicated
checks for platform timer for all platforms. pci irq enable/disable can also
benefit from the platform setup layer, but this part is not complete in this
patch, should be able to include visws. e.g.
pcibios_enable_irq = &pci_visws_enable_irq;
pcibios_disable_irq = &pci_visws_disable_irq;
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
---
arch/x86/include/asm/apic.h | 2 ++
arch/x86/include/asm/pci_x86.h | 2 ++
arch/x86/include/asm/platform.h | 11 +++++++++++
arch/x86/kernel/apic/io_apic.c | 6 +++---
arch/x86/kernel/platform_setup.c | 4 ++++
arch/x86/pci/irq.c | 11 +++++++----
6 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 4f2d26d..6698f3b 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -85,6 +85,8 @@ extern u32 safe_xapic_wait_icr_idle(void);
extern void xapic_icr_write(u32, u32);
extern int setup_profiling_timer(unsigned int);
extern void pre_init_apic_IRQ(void);
+extern void default_check_timer(void);
+extern int timer_irq_works(void);
static inline void native_apic_mem_write(u32 reg, u32 v)
{
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index b399988..118a62d 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -116,6 +116,8 @@ extern int __init pci_visws_init(void);
extern int __init pci_numaq_init(void);
extern int __init pcibios_init(void);
+extern int pirq_enable_irq(struct pci_dev *dev);
+
/* pci-mmconfig.c */
extern int __init pci_mmcfg_arch_init(void);
diff --git a/arch/x86/include/asm/platform.h b/arch/x86/include/asm/platform.h
index 1cea28c..d698f68 100644
--- a/arch/x86/include/asm/platform.h
+++ b/arch/x86/include/asm/platform.h
@@ -6,6 +6,7 @@
struct mpc_bus;
struct mpc_cpu;
struct mpc_table;
+struct pci_dev;
/**
* struct platform_setup_quirks - platform specific quirks
@@ -62,6 +63,11 @@ struct platform_setup_irqs {
void (*pre_vector_init)(void);
void (*intr_init)(void);
void (*trap_init)(void);
+
+#ifdef CONFIG_PCI
+ int (*pci_enable_irq)(struct pci_dev *dev);
+ void (*pci_disable_irq)(struct pci_dev *dev);
+#endif
};
/**
@@ -97,6 +103,7 @@ struct platform_setup_timers {
void (*tsc_pre_init)(void);
void (*timer_init)(void);
unsigned long (*calibrate_tsc)(void);
+ void (*check_timers)(void);
};
/**
@@ -127,4 +134,8 @@ extern struct platform_setup_cpuhotplug platform_cpuhotplug_setup;
extern void platform_setup_noop(void);
extern void platform_setup_uint_noop(unsigned int unused);
+#ifdef CONFIG_PCI
+extern int pirq_enable_irq(struct pci_dev *dev);
+#endif
+
#endif
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 25a5b72..4418daa 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2155,7 +2155,7 @@ __setup("no_timer_check", notimercheck);
* - if this function detects that timer IRQs are defunct, then we fall
* back to ISA timer IRQs
*/
-static int __init timer_irq_works(void)
+int __init timer_irq_works(void)
{
unsigned long t1 = jiffies;
unsigned long flags;
@@ -2868,7 +2868,7 @@ int timer_through_8259 __initdata;
*
* FIXME: really need to revamp this for all platforms.
*/
-static inline void __init check_timer(void)
+inline void __init default_check_timer(void)
{
struct irq_desc *desc = irq_to_desc(0);
struct irq_cfg *cfg = desc->chip_data;
@@ -3084,7 +3084,7 @@ void __init setup_IO_APIC(void)
sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
- check_timer();
+ platform_setup.timers.check_timers();
}
/*
diff --git a/arch/x86/kernel/platform_setup.c b/arch/x86/kernel/platform_setup.c
index 9752eff..b60fb5b 100644
--- a/arch/x86/kernel/platform_setup.c
+++ b/arch/x86/kernel/platform_setup.c
@@ -44,6 +44,9 @@ struct __initdata platform_setup_ops platform_setup = {
.pre_vector_init = init_ISA_irqs,
.intr_init = native_init_IRQ,
.trap_init = platform_setup_noop,
+#ifdef CONFIG_PCI
+ .pci_enable_irq = pirq_enable_irq,
+#endif
},
.oem = {
@@ -61,6 +64,7 @@ struct __initdata platform_setup_ops platform_setup = {
.tsc_pre_init = platform_setup_noop,
.timer_init = hpet_time_init,
.calibrate_tsc = native_calibrate_tsc,
+ .check_timers = default_check_timer,
},
.quirks = {
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 0696d50..c31bd03 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/smp.h>
#include <asm/io_apic.h>
+#include <asm/platform_feature.h>
#include <linux/irq.h>
#include <linux/acpi.h>
#include <asm/pci_x86.h>
@@ -26,8 +27,6 @@ static int acer_tm360_irqrouting;
static struct irq_routing_table *pirq_table;
-static int pirq_enable_irq(struct pci_dev *dev);
-
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
@@ -1022,6 +1021,10 @@ static void __init pcibios_fixup_irqs(void)
u8 pin;
DBG(KERN_DEBUG "PCI: IRQ fixup\n");
+ if (!platform_has(X86_PLATFORM_FEATURE_BIOS)) {
+ DBG(KERN_DEBUG "PCI: No BIOS, skip IRQ fixup\n");
+ return;
+ }
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
/*
* If the BIOS has set an out of range IRQ number, just
@@ -1142,7 +1145,7 @@ int __init pcibios_irq_init(void)
pirq_table = NULL;
}
- pcibios_enable_irq = pirq_enable_irq;
+ pcibios_enable_irq = platform_setup.irqs.pci_enable_irq;
pcibios_fixup_irqs();
@@ -1185,7 +1188,7 @@ void pcibios_penalize_isa_irq(int irq, int active)
pirq_penalize_isa_irq(irq, active);
}
-static int pirq_enable_irq(struct pci_dev *dev)
+int pirq_enable_irq(struct pci_dev *dev)
{
u8 pin;
--
1.5.6.5
^ permalink raw reply related [flat|nested] 53+ messages in thread
* Re: [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown
2009-08-28 21:52 ` [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown Pan, Jacob jun
@ 2009-08-29 16:58 ` Thomas Gleixner
0 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-29 16:58 UTC (permalink / raw)
To: Pan, Jacob jun
Cc: LKML, x86 team, Andrew Morton, Peter Zijlstra, Arjan van de Veen,
Avi Kivity, Rusty Russell, Alok N Kataria, Jeremy Fitzhardinge
On Fri, 28 Aug 2009, Pan, Jacob jun wrote:
> >From 2de4f68e7b0403bb39954d7c2e3d5097d0e6e3ac Mon Sep 17 00:00:00 2001
> From: Jacob Pan <jacob.jun.pan@intel.com>
> Date: Thu, 11 Jun 2009 20:34:47 -0700
> Subject: [PATCH] x86/boot: adding hw subarch ID for Moorestown
>
> x86 bootprotocol 2.07 has introduced hardware_subarch ID in the boot
> parameters provided by FW. We use it to identify Moorestown platforms.
>
> The subarchitecture ID will help select a set of platform features and
> x86_quirks.
>
> Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
> ---
> Documentation/x86/boot.txt | 1 +
> arch/x86/include/asm/bootparam.h | 11 +++++++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
> index 8da3a79..30b43e1 100644
> --- a/Documentation/x86/boot.txt
> +++ b/Documentation/x86/boot.txt
> @@ -599,6 +599,7 @@ Protocol: 2.07+
> 0x00000000 The default x86/PC environment
> 0x00000001 lguest
> 0x00000002 Xen
> + 0x00000003 Moorestown MID
>
> Field name: hardware_subarch_data
> Type: write (subarch-dependent)
> diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
> index 1724e8d..631cae9 100644
> --- a/arch/x86/include/asm/bootparam.h
> +++ b/arch/x86/include/asm/bootparam.h
> @@ -109,4 +109,15 @@ struct boot_params {
> __u8 _pad9[276]; /* 0xeec */
> } __attribute__((packed));
>
> +#define N_X86_SUBARCHS 4
Grr.
> +enum {
> + X86_SUBARCH_PC = 0,
> + X86_SUBARCH_LGUEST,
> + X86_SUBARCH_XEN,
> + X86_SUBARCH_MRST,
X86_NR_SUBARCHS,
perhaps ?
Also this patch will result in boot failure when paravirt is
enabled. head_32.S wants to be tweaked as well.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
@ 2009-08-29 16:59 ` Thomas Gleixner
0 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-29 16:59 UTC (permalink / raw)
To: Pan, Jacob jun
Cc: Jeremy Fitzhardinge, LKML, x86 team, Andrew Morton,
Peter Zijlstra, Arjan van de Veen, Avi Kivity, Rusty Russell,
Alok N Kataria
On Fri, 28 Aug 2009, Pan, Jacob jun wrote:
> Based on platform_setup patchset posted by tglx (http://lkml.org/lkml/2009/8/21/358)
>
> These Moorestown patches have become much simplified once ported to the new
> platform_setup layer.
>
> Now the platform feature flags are less useful, in fact they
> are only used in separating ioapic and 8259 now, so once the interrupt
> controller code is drivernized, we would not need the platform feature flags
> in the core.
I don't think that we need big changes in the ioapic code. All you
need can be done with way simpler tweaking.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC PATCH 3/7] x86: add moorestown specific platform setup code
2009-08-28 21:52 ` [RFC PATCH 3/7] x86: add moorestown specific platform setup code Pan, Jacob jun
@ 2009-08-29 17:20 ` Thomas Gleixner
0 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-29 17:20 UTC (permalink / raw)
To: Pan, Jacob jun
Cc: Jeremy Fitzhardinge, LKML, x86 team, Andrew Morton,
Peter Zijlstra, Arjan van de Veen, Avi Kivity, Rusty Russell,
Alok N Kataria
On Fri, 28 Aug 2009, Pan, Jacob jun wrote:
> >From dbb97928dc27061b56fc86b9b37f71f54bbafb59 Mon Sep 17 00:00:00 2001
> From: Jacob Pan <jacob.jun.pan@intel.com>
> Date: Fri, 28 Aug 2009 08:31:45 -0700
> Subject: [PATCH] x86: add moorestown specific platform setup code
>
> This patch fills in platform_setup functions for Moorestown. The abstraction
> is used to integarte into pc compaitible boot flow.
Your patch series is horrible as it breaks left and right. Patches
need to be ordered so they compile and boot in any stage.
> Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
> ---
> arch/x86/include/asm/setup.h | 8 ++
> arch/x86/kernel/Makefile | 1 +
> arch/x86/kernel/mrst.c | 149 ++++++++++++++++++++++++++++++++++++++++++
> arch/x86/kernel/setup.c | 1 +
> 4 files changed, 159 insertions(+), 0 deletions(-)
> create mode 100644 arch/x86/kernel/mrst.c
>
> diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
> index 055b778..2ef1514 100644
> --- a/arch/x86/include/asm/setup.h
> +++ b/arch/x86/include/asm/setup.h
> @@ -49,6 +49,14 @@ extern void reserve_standard_io_resources(void);
> extern void i386_reserve_resources(void);
> extern void setup_default_timer_irq(void);
>
> +#ifdef CONFIG_MRST
> +extern void mrst_early_detect(void);
> +extern void setup_mrst_default_feature(void);
Why ? The function is inline in mrst.c.
> +++ b/arch/x86/kernel/mrst.c
> @@ -0,0 +1,149 @@
> +/*
> + * mrst.c: Intel Moorestown platform specific setup code
> + *
> + * (C) Copyright 2008 Intel Corporation
> + * Author: Jacob Pan (jacob.jun.pan@intel.com)
> + *
> + * 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; version 2
> + * of the License.
> + *
> + * Note:
> + *
> + */
> +
> +#include <linux/stackprotector.h>
> +#include <linux/spi/spi.h>
> +#include <linux/i2c.h>
> +#include <linux/sfi.h>
> +#include <linux/i2c/pca953x.h>
> +#include <linux/spi/langwell_pmic_gpio.h>
> +#include <linux/gpio_keys.h>
> +#include <linux/input.h>
> +#include <linux/platform_device.h>
> +#include <linux/pci.h>
> +
> +#include <asm/platform_feature.h>
> +#include <asm/apb_timer.h>
> +#include <asm/apic.h>
> +#include <asm/hw_irq.h>
> +#include <asm/setup.h>
> +#include <asm/io.h>
Do we really need that whole bunch of includes ?
> +#define LANGWELL_GPIO_ALT_ADDR 0xff12c038
> +#define MRST_I2C_BUSNUM 3
That should be in the appropriate header file aside of being unused.
> +static inline void __init mrst_pre_intr_init(void)
> +{
> + pre_init_apic_IRQ();
> +}
Later on you assign that function to:
> + platform_setup.irqs.pre_vector_init = mrst_pre_intr_init;
I don't think that's correct. You need the early setup of the APIC
when you setup the APBT timer, but that's way after pre_vector_init.
Please do not use random platform functions just because they are
available.
The setup of the APIC to make your timer work should be done either in
context of the timer init function or in some appropriate place before
that.
> +/*
> + * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
> + * APBT but cmdline option can also override it.
We have the platform functions to avoid constructs like this. If you
set the function pointer to mrst_setup_secondary_clock in your
platform init the you can check the disable_apbt_percpu there or
restore the default in the function which evaluates the command line
option.
> + */
> +static void __init mrst_setup_secondary_clock(void)
Needs to be __cpuinit. If you have CPU_HOTPLUG enabled, which you need
for suspend/hibernate this function will be gone at the point you
access it.
> +{
> + if (disable_apbt_percpu)
> + return setup_secondary_APIC_clock();
> + else {
> +#ifdef CONFIG_CC_STACKPROTECTOR
> + /*
> + * TBD:
> + * this is to avoid false stack corruption panic since
> + * request_irq will be called early for secondary apbt clock.
> + */
> + boot_init_stack_canary();
Eeek. Why is this related to request_irq ?
> +#endif
> + apbt_setup_secondary_clock();
> + }
> +}
> +
> +static void __init mrst_check_timer(void)
> +{
> + if (timer_irq_works())
> + printk(KERN_INFO "APB timer works\n");
> + else
> + panic("Check APB timer failed\n");
> +}
Errm. You add a new platform function just to add printk debug noise ?
> +static unsigned long __init mrst_calibrate_tsc(void)
> +{
> + unsigned long flags, fast_calibrate;
> +
> + local_irq_save(flags);
> + fast_calibrate = apbt_quick_calibrate();
> + local_irq_restore(flags);
> +
> + if (fast_calibrate)
> + return fast_calibrate;
> +
> + return 0;
return fast_calibrate;
might do the same with less obfuscation.
> +}
> +inline void setup_mrst_default_feature(void)
> +{
> + /*
> + * x86pc default platform setup ops are setup prior to start_kernel
> + * we override default platform_setup calls for Moorestown
> + */
> + platform_setup.resources.reserve_ebda_region = platform_setup_noop;
See below.
> +void __init mrst_early_detect(void)
> +{
> + int subarch_id = boot_params.hdr.hardware_subarch;
> +
> + if ((subarch_id >= 0) && (subarch_id < N_X86_SUBARCHS)) {
What's the purpose of this check ? Either it's X86_SUBARCH_MRST or
not.
> + if (subarch_id == X86_SUBARCH_MRST) {
> + setup_mrst_default_feature();
> @@ -692,6 +692,7 @@ void __init setup_arch(char **cmdline_p)
> #ifdef CONFIG_X86_32
> memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
> visws_early_detect();
> + mrst_early_detect();
That call is too late.
You override platform_setup.resources.reserve_ebda_region _AFTER_ it
has been called.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [RFC PATCH 7/7] x86: add more platform_setup functions
2009-08-28 21:53 ` [RFC PATCH 7/7] x86: add more platform_setup functions Pan, Jacob jun
@ 2009-08-29 17:31 ` Thomas Gleixner
0 siblings, 0 replies; 53+ messages in thread
From: Thomas Gleixner @ 2009-08-29 17:31 UTC (permalink / raw)
To: Pan, Jacob jun
Cc: Jeremy Fitzhardinge, LKML, x86 team, Andrew Morton,
Peter Zijlstra, Arjan van de Veen, Avi Kivity, Rusty Russell,
Alok N Kataria
On Fri, 28 Aug 2009, Pan, Jacob jun wrote:
> >From fbfe65d64e4dbb31940d31a59e080bfa15d121bb Mon Sep 17 00:00:00 2001
> From: Jacob Pan <jacob.jun.pan@intel.com>
> Date: Wed, 8 Jul 2009 16:51:42 -0700
> Subject: [PATCH] x86: RFC add more platform_setup functions
>
> check_timer can be abstracted so that we don't have to do the complicated
> checks for platform timer for all platforms.
Well, if it's necessary then we replace it, but the code you showed in
an earlier patch is just adding debug cruft. So what's the point ?
> pci irq enable/disable can also
> benefit from the platform setup layer, but this part is not complete in this
> patch, should be able to include visws. e.g.
Please provide one patch per feature / change.
> pcibios_enable_irq = &pci_visws_enable_irq;
> pcibios_disable_irq = &pci_visws_disable_irq;
No, this is patently wrong. You abstract at the wrong point. If
abstraction of the pci init is necessary then the various #ifdeffed
function calls in legacy.c:pci_subsys_init() have to be platformized.
> extern int __init pci_mmcfg_arch_init(void);
> diff --git a/arch/x86/include/asm/platform.h b/arch/x86/include/asm/platform.h
> index 1cea28c..d698f68 100644
> --- a/arch/x86/include/asm/platform.h
> +++ b/arch/x86/include/asm/platform.h
> @@ -6,6 +6,7 @@
> struct mpc_bus;
> struct mpc_cpu;
> struct mpc_table;
> +struct pci_dev;
>
> /**
> * struct platform_setup_quirks - platform specific quirks
> @@ -62,6 +63,11 @@ struct platform_setup_irqs {
> void (*pre_vector_init)(void);
> void (*intr_init)(void);
> void (*trap_init)(void);
> +
> +#ifdef CONFIG_PCI
> + int (*pci_enable_irq)(struct pci_dev *dev);
> + void (*pci_disable_irq)(struct pci_dev *dev);
> +#endif
PCI stuff does not belong to irq. It needs a separate data
structure. Also using the function pointers just to assign them later
to some other function pointer is pointless. The code can be
restructured so you can just tweak the existing function pointer.
Also I avoided #ifdefs in the platform code on purpose. The few bytes
you spare in the init structure are not worth the #ifdef mess which is
needed all over the place.
Thanks,
tglx
^ permalink raw reply [flat|nested] 53+ messages in thread
end of thread, other threads:[~2009-08-29 17:33 UTC | newest]
Thread overview: 53+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-21 21:29 [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 01/32] x86: Add platform_setup infrastructure Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 02/32] x86: Add probe_roms to platform_setup Thomas Gleixner
2009-08-21 22:23 ` Jeremy Fitzhardinge
2009-08-21 22:36 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 0/7] x86/boot: Moorestown patch set based on platform_set abstraction Pan, Jacob jun
2009-08-29 16:59 ` Thomas Gleixner
2009-08-28 21:52 ` [RFC PATCH 2/7] x86: introduce a set of platform feature flags Pan, Jacob jun
2009-08-28 21:52 ` [RFC PATCH 3/7] x86: add moorestown specific platform setup code Pan, Jacob jun
2009-08-29 17:20 ` Thomas Gleixner
2009-08-28 21:53 ` [RFC PATCH 4/7] x86/apbt: Moorestown APB system timer driver Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 5/7] x86/apic: decouple legacy irq handling in ioapic Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 6/7] x86/apic: Early setup IOAPIC for APB timer Pan, Jacob jun
2009-08-28 21:53 ` [RFC PATCH 7/7] x86: add more platform_setup functions Pan, Jacob jun
2009-08-29 17:31 ` Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 03/32] x86: Add request_standard_resources to platform_setup Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 04/32] x86: Add reserve_ebda_region " Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 05/32] x86: Move memory_setup to platform Thomas Gleixner
2009-08-21 21:29 ` [RFC patch 06/32] x86: Sanitize smp_record and move it to platform_setup Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 07/32] x86: Move ioapic_ids_setup " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 08/32] x86: Move mpc_apic_id " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 09/32] x86: Move smp_read_mpc_oem " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 10/32] x86: Move mpc_oem_pci_bus " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 11/32] x86: Move oem_bus_info " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 12/32] x86: Move get/find_smp_config " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 13/32] x86: Move pre_intr_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 14/32] x86: Move irq_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 15/32] x86: Move traps_init " Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 16/32] x86: Replace ARCH_SETUP by a proper platform function Thomas Gleixner
2009-08-21 22:30 ` Jeremy Fitzhardinge
2009-08-21 23:42 ` Thomas Gleixner
2009-08-28 21:52 ` [PATCH 1/7] x86/boot: adding hw subarch ID for Moorestown Pan, Jacob jun
2009-08-29 16:58 ` Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 17/32] x86: Move paravirt banner printout to platform Thomas Gleixner
2009-08-21 21:30 ` [RFC patch 18/32] x86: Move paravirt pagetable_setup " Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 19/32] x86: Move xen_post_allocator_init into xen_pagetable_setup_done Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 20/32] x86: Move percpu clockevents setup to platform Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 21/32] x86: Add timer_init " Thomas Gleixner
2009-08-24 6:48 ` Andrey Panin
2009-08-21 21:31 ` [RFC patch 22/32] x86: Remove do_timer hook Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 23/32] x86: Prepare unification of time_32/64.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 24/32] x86: Simplify timer_ack magic in time_32.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 25/32] x86: Remove mca bus ifdef from timer interrupt Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 26/32] x86: Make timer setup and global variables the same in time_32/64.c Thomas Gleixner
2009-08-21 21:31 ` [RFC patch 27/32] x86: Move calibrate_cpu to tsc.c Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 28/32] x86: time_32/64.c unify profile_pc Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 29/32] x86: Replace the now identical time_32/64.c by time.c Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 30/32] x86: Move tsc_calibration to platform Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 31/32] init: Move sched_clock_init after late_time_init Thomas Gleixner
2009-08-21 21:32 ` [RFC patch 32/32] x86: Move tsc_init to late_time_init Thomas Gleixner
2009-08-21 22:19 ` [RFC patch 00/32] x86: Refactor the setup code to provide a base for embedded platforms Jeremy Fitzhardinge
2009-08-22 10:57 ` Ingo Molnar
2009-08-23 9:15 ` Thomas Gleixner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox