From 8a6d48c0542876eb3acfc0970c0ab7872db08d5f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 6 Dec 2009 05:26:23 +0100 Subject: check in the original version of dde linux26. --- libdde_linux26/lib/src/arch/l4/timer.c | 184 +++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 libdde_linux26/lib/src/arch/l4/timer.c (limited to 'libdde_linux26/lib/src/arch/l4/timer.c') diff --git a/libdde_linux26/lib/src/arch/l4/timer.c b/libdde_linux26/lib/src/arch/l4/timer.c new file mode 100644 index 00000000..ea04b67e --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/timer.c @@ -0,0 +1,184 @@ +#include "local.h" + +#include +#include +#include + +DECLARE_INITVAR(dde26_timer); + +/* Definitions from linux/kernel/timer.c */ + +/* + * per-CPU timer vector definitions: + */ +#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6) +#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8) +#define TVN_SIZE (1 << TVN_BITS) +#define TVR_SIZE (1 << TVR_BITS) +#define TVN_MASK (TVN_SIZE - 1) +#define TVR_MASK (TVR_SIZE - 1) + +typedef struct tvec_s { + struct list_head vec[TVN_SIZE]; +} tvec_t; + +typedef struct tvec_root_s { + struct list_head vec[TVR_SIZE]; +} tvec_root_t; + +struct tvec_base { + spinlock_t lock; + struct timer_list *running_timer; + unsigned long timer_jiffies; + tvec_root_t tv1; + tvec_t tv2; + tvec_t tv3; + tvec_t tv4; + tvec_t tv5; +} ____cacheline_aligned_in_smp; + +typedef struct tvec_t_base_s tvec_base_t; + +struct tvec_base boot_tvec_bases __attribute__((unused)); + +static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) __attribute__((unused)) = &boot_tvec_bases; + +void init_timer(struct timer_list *timer) +{ + timer->ddekit_timer_id = DDEKIT_INVALID_TIMER_ID; +} + +void add_timer(struct timer_list *timer) +{ + CHECK_INITVAR(dde26_timer); + /* DDE2.6 uses jiffies and HZ as exported from L4IO. Therefore + * we just need to hand over the timeout to DDEKit. */ + timer->ddekit_timer_id = ddekit_add_timer((void *)timer->function, + (void *)timer->data, + timer->expires); +} + + +void add_timer_on(struct timer_list *timer, int cpu) +{ + add_timer(timer); +} + + +int del_timer(struct timer_list * timer) +{ + int ret; + CHECK_INITVAR(dde26_timer); + ret = ddekit_del_timer(timer->ddekit_timer_id); + timer->ddekit_timer_id = DDEKIT_INVALID_TIMER_ID; + + return ret >= 0; +} + +int del_timer_sync(struct timer_list *timer) +{ + return del_timer(timer); +} + + +int __mod_timer(struct timer_list *timer, unsigned long expires) +{ + /* XXX: Naive implementation. If we really need to be fast with + * this function, we can implement a faster version inside + * the DDEKit. Bjoern just does not think that this is the + * case. + */ + int r; + + CHECK_INITVAR(dde26_timer); + r = del_timer(timer); + + timer->expires = expires; + add_timer(timer); + + return (r > 0); +} + + +int mod_timer(struct timer_list *timer, unsigned long expires) +{ + return __mod_timer(timer, expires); +} + + +int timer_pending(const struct timer_list *timer) +{ + CHECK_INITVAR(dde26_timer); + /* There must be a valid DDEKit timer ID in the timer field + * *AND* it must be pending in the DDEKit. + */ + return ((timer->ddekit_timer_id != DDEKIT_INVALID_TIMER_ID) + && ddekit_timer_pending(timer->ddekit_timer_id)); +} + + +/** + * msleep - sleep safely even with waitqueue interruptions + * @msecs: Time in milliseconds to sleep for + */ +void msleep(unsigned int msecs) +{ + ddekit_thread_msleep(msecs); +} + + +void __const_udelay(unsigned long xloops) +{ + ddekit_thread_usleep(xloops); +} + + +void __udelay(unsigned long usecs) +{ + ddekit_thread_usleep(usecs); +} + + +void __ndelay(unsigned long nsecs) +{ + ddekit_thread_nsleep(nsecs); +} + + +void __init l4dde26_init_timers(void) +{ + ddekit_init_timers(); + + l4dde26_process_from_ddekit(ddekit_get_timer_thread()); + + INITIALIZE_INITVAR(dde26_timer); +} + +core_initcall(l4dde26_init_timers); + +extern unsigned long volatile __jiffy_data jiffies; + +__attribute__((weak)) void do_gettimeofday (struct timeval *tv) +{ + WARN_UNIMPL; +} + +struct timespec current_fs_time(struct super_block *sb) +{ + struct timespec now = {0,0}; + WARN_UNIMPL; + return now; +} + +ktime_t ktime_get_real(void) +{ + struct timespec now = {0,0}; + WARN_UNIMPL; + return timespec_to_ktime(now); +} + + +void native_io_delay(void) +{ + udelay(2); +} -- cgit v1.2.3 From 145623ebcf753252a36a3e67128fb9879d0001e4 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 5 Jan 2010 16:51:25 +0100 Subject: call initcall functions explicitly. --- libdde_linux26/contrib/arch/x86/kernel/pci-dma.c | 2 +- libdde_linux26/contrib/block/blk-ioc.c | 2 +- libdde_linux26/contrib/block/blk-settings.c | 2 +- libdde_linux26/contrib/block/blk-softirq.c | 2 +- libdde_linux26/contrib/block/noop-iosched.c | 2 +- libdde_linux26/contrib/fs/bio.c | 2 +- libdde_linux26/contrib/mm/backing-dev.c | 2 +- libdde_linux26/contrib/net/core/neighbour.c | 2 +- libdde_linux26/lib/src/arch/l4/init.c | 48 +++++++++++++++++++++++- libdde_linux26/lib/src/arch/l4/local.h | 2 +- libdde_linux26/lib/src/arch/l4/page_alloc.c | 2 +- libdde_linux26/lib/src/arch/l4/pci.c | 2 +- libdde_linux26/lib/src/arch/l4/timer.c | 2 +- libdde_linux26/lib/src/block/genhd.c | 2 +- libdde_linux26/lib/src/drivers/pci/pci-driver.c | 2 +- libdde_linux26/lib/src/drivers/pci/pci.c | 2 +- libdde_linux26/lib/src/drivers/pci/probe.c | 2 +- libdde_linux26/lib/src/fs/char_dev.c | 2 +- libdde_linux26/lib/src/kernel/workqueue.c | 2 +- libdde_linux26/lib/src/net/core/dev.c | 2 +- libdde_linux26/lib/src/net/core/net_namespace.c | 2 +- 21 files changed, 66 insertions(+), 22 deletions(-) (limited to 'libdde_linux26/lib/src/arch/l4/timer.c') diff --git a/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c b/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c index b2542853..80e9f10e 100644 --- a/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c +++ b/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c @@ -282,7 +282,7 @@ void pci_iommu_shutdown(void) gart_iommu_shutdown(); } /* Must execute after PCI subsystem */ -fs_initcall(pci_iommu_init); +//fs_initcall(pci_iommu_init); #ifdef CONFIG_PCI /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ diff --git a/libdde_linux26/contrib/block/blk-ioc.c b/libdde_linux26/contrib/block/blk-ioc.c index 012f065a..e067a82a 100644 --- a/libdde_linux26/contrib/block/blk-ioc.c +++ b/libdde_linux26/contrib/block/blk-ioc.c @@ -177,4 +177,4 @@ static int __init blk_ioc_init(void) sizeof(struct io_context), 0, SLAB_PANIC, NULL); return 0; } -subsys_initcall(blk_ioc_init); +//subsys_initcall(blk_ioc_init); diff --git a/libdde_linux26/contrib/block/blk-settings.c b/libdde_linux26/contrib/block/blk-settings.c index 59fd05d9..ad0af33c 100644 --- a/libdde_linux26/contrib/block/blk-settings.c +++ b/libdde_linux26/contrib/block/blk-settings.c @@ -469,4 +469,4 @@ static int __init blk_settings_init(void) blk_max_pfn = max_pfn - 1; return 0; } -subsys_initcall(blk_settings_init); +//subsys_initcall(blk_settings_init); diff --git a/libdde_linux26/contrib/block/blk-softirq.c b/libdde_linux26/contrib/block/blk-softirq.c index ce0efc6b..e9a18af7 100644 --- a/libdde_linux26/contrib/block/blk-softirq.c +++ b/libdde_linux26/contrib/block/blk-softirq.c @@ -172,4 +172,4 @@ static __init int blk_softirq_init(void) register_hotcpu_notifier(&blk_cpu_notifier); return 0; } -subsys_initcall(blk_softirq_init); +//subsys_initcall(blk_softirq_init); diff --git a/libdde_linux26/contrib/block/noop-iosched.c b/libdde_linux26/contrib/block/noop-iosched.c index 075cb108..e78234a9 100644 --- a/libdde_linux26/contrib/block/noop-iosched.c +++ b/libdde_linux26/contrib/block/noop-iosched.c @@ -114,7 +114,7 @@ static void __exit noop_exit(void) elv_unregister(&elevator_noop); } -subsys_initcall(noop_init); +//subsys_initcall(noop_init); module_exit(noop_exit); diff --git a/libdde_linux26/contrib/fs/bio.c b/libdde_linux26/contrib/fs/bio.c index d4f06327..a59a1488 100644 --- a/libdde_linux26/contrib/fs/bio.c +++ b/libdde_linux26/contrib/fs/bio.c @@ -1615,7 +1615,7 @@ static int __init init_bio(void) return 0; } -subsys_initcall(init_bio); +//subsys_initcall(init_bio); EXPORT_SYMBOL(bio_alloc); EXPORT_SYMBOL(bio_kmalloc); diff --git a/libdde_linux26/contrib/mm/backing-dev.c b/libdde_linux26/contrib/mm/backing-dev.c index 8e858744..32f604bc 100644 --- a/libdde_linux26/contrib/mm/backing-dev.c +++ b/libdde_linux26/contrib/mm/backing-dev.c @@ -167,7 +167,7 @@ static __init int bdi_class_init(void) return 0; } -postcore_initcall(bdi_class_init); +//postcore_initcall(bdi_class_init); int bdi_register(struct backing_dev_info *bdi, struct device *parent, const char *fmt, ...) diff --git a/libdde_linux26/contrib/net/core/neighbour.c b/libdde_linux26/contrib/net/core/neighbour.c index 278a142d..4a90e322 100644 --- a/libdde_linux26/contrib/net/core/neighbour.c +++ b/libdde_linux26/contrib/net/core/neighbour.c @@ -2820,5 +2820,5 @@ static int __init neigh_init(void) return 0; } -subsys_initcall(neigh_init); +//subsys_initcall(neigh_init); diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c index 79112f78..1d44bf97 100644 --- a/libdde_linux26/lib/src/arch/l4/init.c +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -26,8 +26,52 @@ void __init __attribute__((used)) l4dde26_init(void) void l4dde26_do_initcalls(void) { + extern void dde_page_cache_init (void); + extern void pci_iommu_init (void); + extern void init_workqueues (void); + extern void pci_init (void); + extern void pci_driver_init (void); + extern void pcibus_class_init (void); + extern void net_dev_init (void); + extern void neigh_init (void); + extern void net_ns_init (void); + extern void blk_ioc_init (void); + extern void blk_settings_init (void); + extern void blk_softirq_init (void); + extern void genhd_device_init (void); + extern void noop_init (void); + extern void bdi_class_init (void); + extern void init_bio (void); + extern void chrdev_init (void); /* finally, let DDEKit perform all the initcalls */ - ddekit_do_initcalls(); +// ddekit_do_initcalls(); + /* 1000: pure_, core_ */ + l4dde26_init (); + l4dde26_init_timers (); + net_ns_init (); + dde_page_cache_init (); + init_workqueues (); + chrdev_init (); + /* 1001: postcore_ */ + pci_driver_init (); + pcibus_class_init (); + bdi_class_init (); + /* 1002: arch_ */ + l4dde26_init_pci (); + /* 1003: subsys_ */ + net_dev_init (); + neigh_init (); + blk_ioc_init (); + blk_settings_init (); + blk_softirq_init (); + genhd_device_init (); + noop_init (); + init_bio (); + /* 1004: fs_ */ + pci_iommu_init (); + /* 1005: device_ */ + pci_init (); + /* 1006: late_ */ } -dde_initcall(l4dde26_init); +//dde_initcall(l4dde26_init); diff --git a/libdde_linux26/lib/src/arch/l4/local.h b/libdde_linux26/lib/src/arch/l4/local.h index d834a9db..275c745b 100644 --- a/libdde_linux26/lib/src/arch/l4/local.h +++ b/libdde_linux26/lib/src/arch/l4/local.h @@ -6,7 +6,7 @@ #include #include #include -#include +//#include #include #include #include diff --git a/libdde_linux26/lib/src/arch/l4/page_alloc.c b/libdde_linux26/lib/src/arch/l4/page_alloc.c index e887bd51..a418cc65 100644 --- a/libdde_linux26/lib/src/arch/l4/page_alloc.c +++ b/libdde_linux26/lib/src/arch/l4/page_alloc.c @@ -273,4 +273,4 @@ static void __init dde_page_cache_init(void) INIT_HLIST_HEAD(&dde_page_cache[i]); } -core_initcall(dde_page_cache_init); +//core_initcall(dde_page_cache_init); diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index 2a0391f2..e86c42e8 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -186,4 +186,4 @@ void __init l4dde26_init_pci(void) INITIALIZE_INITVAR(dde26_pci); } -arch_initcall(l4dde26_init_pci); +//arch_initcall(l4dde26_init_pci); diff --git a/libdde_linux26/lib/src/arch/l4/timer.c b/libdde_linux26/lib/src/arch/l4/timer.c index ea04b67e..f80aa5d3 100644 --- a/libdde_linux26/lib/src/arch/l4/timer.c +++ b/libdde_linux26/lib/src/arch/l4/timer.c @@ -154,7 +154,7 @@ void __init l4dde26_init_timers(void) INITIALIZE_INITVAR(dde26_timer); } -core_initcall(l4dde26_init_timers); +//core_initcall(l4dde26_init_timers); extern unsigned long volatile __jiffy_data jiffies; diff --git a/libdde_linux26/lib/src/block/genhd.c b/libdde_linux26/lib/src/block/genhd.c index 921cebff..9028c31c 100644 --- a/libdde_linux26/lib/src/block/genhd.c +++ b/libdde_linux26/lib/src/block/genhd.c @@ -812,7 +812,7 @@ static int __init genhd_device_init(void) return 0; } -subsys_initcall(genhd_device_init); +//subsys_initcall(genhd_device_init); static ssize_t disk_range_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/libdde_linux26/lib/src/drivers/pci/pci-driver.c b/libdde_linux26/lib/src/drivers/pci/pci-driver.c index 199ec8a7..ba4e5108 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci-driver.c +++ b/libdde_linux26/lib/src/drivers/pci/pci-driver.c @@ -997,7 +997,7 @@ static int __init pci_driver_init(void) return bus_register(&pci_bus_type); } -postcore_initcall(pci_driver_init); +//postcore_initcall(pci_driver_init); EXPORT_SYMBOL(pci_match_id); EXPORT_SYMBOL(__pci_register_driver); diff --git a/libdde_linux26/lib/src/drivers/pci/pci.c b/libdde_linux26/lib/src/drivers/pci/pci.c index f67bf734..05c7b38d 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci.c +++ b/libdde_linux26/lib/src/drivers/pci/pci.c @@ -2434,7 +2434,7 @@ static int __init pci_setup(char *str) } early_param("pci", pci_setup); -device_initcall(pci_init); +//device_initcall(pci_init); EXPORT_SYMBOL(pci_reenable_device); EXPORT_SYMBOL(pci_enable_device_io); diff --git a/libdde_linux26/lib/src/drivers/pci/probe.c b/libdde_linux26/lib/src/drivers/pci/probe.c index 32da5108..d68a3023 100644 --- a/libdde_linux26/lib/src/drivers/pci/probe.c +++ b/libdde_linux26/lib/src/drivers/pci/probe.c @@ -104,7 +104,7 @@ static int __init pcibus_class_init(void) { return class_register(&pcibus_class); } -postcore_initcall(pcibus_class_init); +//postcore_initcall(pcibus_class_init); /* * Translate the low bits of the PCI base diff --git a/libdde_linux26/lib/src/fs/char_dev.c b/libdde_linux26/lib/src/fs/char_dev.c index 3b8e8b3d..9dd832b4 100644 --- a/libdde_linux26/lib/src/fs/char_dev.c +++ b/libdde_linux26/lib/src/fs/char_dev.c @@ -556,7 +556,7 @@ void __init chrdev_init(void) } #ifndef LIBINPUT -core_initcall(chrdev_init); +//core_initcall(chrdev_init); #endif /* Let modules do char dev stuff */ diff --git a/libdde_linux26/lib/src/kernel/workqueue.c b/libdde_linux26/lib/src/kernel/workqueue.c index 5ad26d9f..d52b22b5 100644 --- a/libdde_linux26/lib/src/kernel/workqueue.c +++ b/libdde_linux26/lib/src/kernel/workqueue.c @@ -1034,5 +1034,5 @@ void __init init_workqueues(void) } #ifdef DDE_LINUX -core_initcall(init_workqueues); +//core_initcall(init_workqueues); #endif diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 1e9247c2..7afb2553 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -5252,7 +5252,7 @@ out: return rc; } -subsys_initcall(net_dev_init); +//subsys_initcall(net_dev_init); EXPORT_SYMBOL(__dev_get_by_index); EXPORT_SYMBOL(__dev_get_by_name); diff --git a/libdde_linux26/lib/src/net/core/net_namespace.c b/libdde_linux26/lib/src/net/core/net_namespace.c index ab5a0a7f..e1f05049 100644 --- a/libdde_linux26/lib/src/net/core/net_namespace.c +++ b/libdde_linux26/lib/src/net/core/net_namespace.c @@ -239,7 +239,7 @@ static int __init net_ns_init(void) return 0; } -pure_initcall(net_ns_init); +//pure_initcall(net_ns_init); #ifdef CONFIG_NET_NS static int register_pernet_operations(struct list_head *list, -- cgit v1.2.3 From 7e7dd7b74a20a08f4f4aacf3943a1881d4113c09 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 5 Jan 2010 16:52:35 +0100 Subject: Don't declare jiffies as a variable. --- libdde_linux26/lib/src/arch/l4/timer.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'libdde_linux26/lib/src/arch/l4/timer.c') diff --git a/libdde_linux26/lib/src/arch/l4/timer.c b/libdde_linux26/lib/src/arch/l4/timer.c index f80aa5d3..8149fe7e 100644 --- a/libdde_linux26/lib/src/arch/l4/timer.c +++ b/libdde_linux26/lib/src/arch/l4/timer.c @@ -156,8 +156,6 @@ void __init l4dde26_init_timers(void) //core_initcall(l4dde26_init_timers); -extern unsigned long volatile __jiffy_data jiffies; - __attribute__((weak)) void do_gettimeofday (struct timeval *tv) { WARN_UNIMPL; -- cgit v1.2.3 From 2680eecc499e43679be098e5834d4f3a62f59a0c Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 16 Jan 2010 01:21:07 +0100 Subject: prepare to use initcall to do initialization. --- libdde_linux26/contrib/arch/x86/kernel/pci-dma.c | 4 +- libdde_linux26/contrib/block/blk-ioc.c | 4 +- libdde_linux26/contrib/block/blk-settings.c | 4 +- libdde_linux26/contrib/block/blk-softirq.c | 4 +- libdde_linux26/contrib/block/noop-iosched.c | 4 +- libdde_linux26/contrib/fs/bio.c | 4 +- libdde_linux26/contrib/mm/backing-dev.c | 4 +- libdde_linux26/contrib/net/core/neighbour.c | 4 +- libdde_linux26/include/linux/init.h | 4 +- libdde_linux26/lib/src/arch/l4/init.c | 49 +----------------------- libdde_linux26/lib/src/arch/l4/local.h | 2 +- libdde_linux26/lib/src/arch/l4/page_alloc.c | 4 +- libdde_linux26/lib/src/arch/l4/pci.c | 2 +- libdde_linux26/lib/src/arch/l4/timer.c | 2 +- libdde_linux26/lib/src/block/genhd.c | 4 +- libdde_linux26/lib/src/drivers/pci/pci-driver.c | 4 +- libdde_linux26/lib/src/drivers/pci/pci.c | 4 +- libdde_linux26/lib/src/drivers/pci/probe.c | 4 +- libdde_linux26/lib/src/fs/char_dev.c | 2 +- libdde_linux26/lib/src/kernel/workqueue.c | 2 +- libdde_linux26/lib/src/net/core/dev.c | 4 +- libdde_linux26/lib/src/net/core/net_namespace.c | 4 +- 22 files changed, 39 insertions(+), 84 deletions(-) (limited to 'libdde_linux26/lib/src/arch/l4/timer.c') diff --git a/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c b/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c index 3a26519b..b2542853 100644 --- a/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c +++ b/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c @@ -263,7 +263,7 @@ int dma_supported(struct device *dev, u64 mask) } EXPORT_SYMBOL(dma_supported); -int __init pci_iommu_init(void) +static int __init pci_iommu_init(void) { calgary_iommu_init(); @@ -282,7 +282,7 @@ void pci_iommu_shutdown(void) gart_iommu_shutdown(); } /* Must execute after PCI subsystem */ -//fs_initcall(pci_iommu_init); +fs_initcall(pci_iommu_init); #ifdef CONFIG_PCI /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ diff --git a/libdde_linux26/contrib/block/blk-ioc.c b/libdde_linux26/contrib/block/blk-ioc.c index b3292405..012f065a 100644 --- a/libdde_linux26/contrib/block/blk-ioc.c +++ b/libdde_linux26/contrib/block/blk-ioc.c @@ -171,10 +171,10 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc) } EXPORT_SYMBOL(copy_io_context); -int __init blk_ioc_init(void) +static int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL); return 0; } -//subsys_initcall(blk_ioc_init); +subsys_initcall(blk_ioc_init); diff --git a/libdde_linux26/contrib/block/blk-settings.c b/libdde_linux26/contrib/block/blk-settings.c index 2178202f..59fd05d9 100644 --- a/libdde_linux26/contrib/block/blk-settings.c +++ b/libdde_linux26/contrib/block/blk-settings.c @@ -463,10 +463,10 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask) } EXPORT_SYMBOL(blk_queue_update_dma_alignment); -int __init blk_settings_init(void) +static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; blk_max_pfn = max_pfn - 1; return 0; } -//subsys_initcall(blk_settings_init); +subsys_initcall(blk_settings_init); diff --git a/libdde_linux26/contrib/block/blk-softirq.c b/libdde_linux26/contrib/block/blk-softirq.c index 34041d14..ce0efc6b 100644 --- a/libdde_linux26/contrib/block/blk-softirq.c +++ b/libdde_linux26/contrib/block/blk-softirq.c @@ -161,7 +161,7 @@ void blk_complete_request(struct request *req) } EXPORT_SYMBOL(blk_complete_request); -__init int blk_softirq_init(void) +static __init int blk_softirq_init(void) { int i; @@ -172,4 +172,4 @@ __init int blk_softirq_init(void) register_hotcpu_notifier(&blk_cpu_notifier); return 0; } -//subsys_initcall(blk_softirq_init); +subsys_initcall(blk_softirq_init); diff --git a/libdde_linux26/contrib/block/noop-iosched.c b/libdde_linux26/contrib/block/noop-iosched.c index a7618fdb..075cb108 100644 --- a/libdde_linux26/contrib/block/noop-iosched.c +++ b/libdde_linux26/contrib/block/noop-iosched.c @@ -101,7 +101,7 @@ static struct elevator_type elevator_noop = { .elevator_owner = THIS_MODULE, }; -int __init noop_init(void) +static int __init noop_init(void) { DEBUG_MSG("here!"); elv_register(&elevator_noop); @@ -114,7 +114,7 @@ static void __exit noop_exit(void) elv_unregister(&elevator_noop); } -//subsys_initcall(noop_init); +subsys_initcall(noop_init); module_exit(noop_exit); diff --git a/libdde_linux26/contrib/fs/bio.c b/libdde_linux26/contrib/fs/bio.c index 7e0238b8..d4f06327 100644 --- a/libdde_linux26/contrib/fs/bio.c +++ b/libdde_linux26/contrib/fs/bio.c @@ -1592,7 +1592,7 @@ static void __init biovec_init_slabs(void) } } -int __init init_bio(void) +static int __init init_bio(void) { bio_slab_max = 2; bio_slab_nr = 0; @@ -1615,7 +1615,7 @@ int __init init_bio(void) return 0; } -//subsys_initcall(init_bio); +subsys_initcall(init_bio); EXPORT_SYMBOL(bio_alloc); EXPORT_SYMBOL(bio_kmalloc); diff --git a/libdde_linux26/contrib/mm/backing-dev.c b/libdde_linux26/contrib/mm/backing-dev.c index 25ebba9a..8e858744 100644 --- a/libdde_linux26/contrib/mm/backing-dev.c +++ b/libdde_linux26/contrib/mm/backing-dev.c @@ -159,7 +159,7 @@ static struct device_attribute bdi_dev_attrs[] = { __ATTR_NULL, }; -__init int bdi_class_init(void) +static __init int bdi_class_init(void) { bdi_class = class_create(THIS_MODULE, "bdi"); bdi_class->dev_attrs = bdi_dev_attrs; @@ -167,7 +167,7 @@ __init int bdi_class_init(void) return 0; } -//postcore_initcall(bdi_class_init); +postcore_initcall(bdi_class_init); int bdi_register(struct backing_dev_info *bdi, struct device *parent, const char *fmt, ...) diff --git a/libdde_linux26/contrib/net/core/neighbour.c b/libdde_linux26/contrib/net/core/neighbour.c index 97ed0aee..e0a03c81 100644 --- a/libdde_linux26/contrib/net/core/neighbour.c +++ b/libdde_linux26/contrib/net/core/neighbour.c @@ -2810,7 +2810,7 @@ EXPORT_SYMBOL(neigh_sysctl_unregister); #endif /* CONFIG_SYSCTL */ -int __init neigh_init(void) +static int __init neigh_init(void) { rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL); rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL); @@ -2822,5 +2822,5 @@ int __init neigh_init(void) return 0; } -//subsys_initcall(neigh_init); +subsys_initcall(neigh_init); diff --git a/libdde_linux26/include/linux/init.h b/libdde_linux26/include/linux/init.h index c7138b66..770546a2 100644 --- a/libdde_linux26/include/linux/init.h +++ b/libdde_linux26/include/linux/init.h @@ -2,7 +2,7 @@ #define _LINUX_INIT_H #ifdef DDE_LINUX -//#include +#include #endif #include @@ -184,7 +184,7 @@ extern void (*late_time_init)(void); #else // DDE_LINUX // XXX: DDE CTORs are executed in reverse order as was done by // Linux' initcalls in earlier versions -//#include +#include #define __define_initcall(level,fn,id) DDEKIT_CTOR(fn,level) #endif diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c index 195b1b23..79112f78 100644 --- a/libdde_linux26/lib/src/arch/l4/init.c +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -26,53 +26,8 @@ void __init __attribute__((used)) l4dde26_init(void) void l4dde26_do_initcalls(void) { - extern void dde_page_cache_init (void); - extern void pci_iommu_init (void); - extern void init_workqueues (void); - extern void pci_init (void); - extern void pci_driver_init (void); - extern void pcibus_class_init (void); - extern void net_dev_init (void); - extern void neigh_init (void); - extern void net_ns_init (void); - extern void blk_ioc_init (void); - extern void blk_settings_init (void); - extern void blk_softirq_init (void); - extern void genhd_device_init (void); - extern void noop_init (void); - extern void bdi_class_init (void); - extern void init_bio (void); - extern void chrdev_init (void); /* finally, let DDEKit perform all the initcalls */ -// ddekit_do_initcalls(); - /* 1000: pure_, core_ */ - l4dde26_init (); - l4dde26_process_init (); - l4dde26_init_timers (); - net_ns_init (); - dde_page_cache_init (); - init_workqueues (); - chrdev_init (); - /* 1001: postcore_ */ - pci_driver_init (); - pcibus_class_init (); - bdi_class_init (); - /* 1002: arch_ */ - l4dde26_init_pci (); - /* 1003: subsys_ */ - net_dev_init (); -// neigh_init (); - blk_ioc_init (); - blk_settings_init (); - blk_softirq_init (); -// genhd_device_init (); - noop_init (); - init_bio (); - /* 1004: fs_ */ - pci_iommu_init (); - /* 1005: device_ */ - pci_init (); - /* 1006: late_ */ + ddekit_do_initcalls(); } -//dde_initcall(l4dde26_init); +dde_initcall(l4dde26_init); diff --git a/libdde_linux26/lib/src/arch/l4/local.h b/libdde_linux26/lib/src/arch/l4/local.h index 275c745b..d834a9db 100644 --- a/libdde_linux26/lib/src/arch/l4/local.h +++ b/libdde_linux26/lib/src/arch/l4/local.h @@ -6,7 +6,7 @@ #include #include #include -//#include +#include #include #include #include diff --git a/libdde_linux26/lib/src/arch/l4/page_alloc.c b/libdde_linux26/lib/src/arch/l4/page_alloc.c index 7c4faa0e..e887bd51 100644 --- a/libdde_linux26/lib/src/arch/l4/page_alloc.c +++ b/libdde_linux26/lib/src/arch/l4/page_alloc.c @@ -264,7 +264,7 @@ void *__init alloc_large_system_hash(const char *tablename, } -void __init dde_page_cache_init(void) +static void __init dde_page_cache_init(void) { printk("Initializing DDE page cache\n"); int i=0; @@ -273,4 +273,4 @@ void __init dde_page_cache_init(void) INIT_HLIST_HEAD(&dde_page_cache[i]); } -//core_initcall(dde_page_cache_init); +core_initcall(dde_page_cache_init); diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index e86c42e8..2a0391f2 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -186,4 +186,4 @@ void __init l4dde26_init_pci(void) INITIALIZE_INITVAR(dde26_pci); } -//arch_initcall(l4dde26_init_pci); +arch_initcall(l4dde26_init_pci); diff --git a/libdde_linux26/lib/src/arch/l4/timer.c b/libdde_linux26/lib/src/arch/l4/timer.c index 8149fe7e..2b657ab4 100644 --- a/libdde_linux26/lib/src/arch/l4/timer.c +++ b/libdde_linux26/lib/src/arch/l4/timer.c @@ -154,7 +154,7 @@ void __init l4dde26_init_timers(void) INITIALIZE_INITVAR(dde26_timer); } -//core_initcall(l4dde26_init_timers); +core_initcall(l4dde26_init_timers); __attribute__((weak)) void do_gettimeofday (struct timeval *tv) { diff --git a/libdde_linux26/lib/src/block/genhd.c b/libdde_linux26/lib/src/block/genhd.c index f9a205f5..921cebff 100644 --- a/libdde_linux26/lib/src/block/genhd.c +++ b/libdde_linux26/lib/src/block/genhd.c @@ -792,7 +792,7 @@ static struct kobject *base_probe(dev_t devt, int *partno, void *data) return NULL; } -int __init genhd_device_init(void) +static int __init genhd_device_init(void) { int error; @@ -812,7 +812,7 @@ int __init genhd_device_init(void) return 0; } -//subsys_initcall(genhd_device_init); +subsys_initcall(genhd_device_init); static ssize_t disk_range_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/libdde_linux26/lib/src/drivers/pci/pci-driver.c b/libdde_linux26/lib/src/drivers/pci/pci-driver.c index 591d9489..199ec8a7 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci-driver.c +++ b/libdde_linux26/lib/src/drivers/pci/pci-driver.c @@ -992,12 +992,12 @@ struct bus_type pci_bus_type = { .pm = PCI_PM_OPS_PTR, }; -int __init pci_driver_init(void) +static int __init pci_driver_init(void) { return bus_register(&pci_bus_type); } -//postcore_initcall(pci_driver_init); +postcore_initcall(pci_driver_init); EXPORT_SYMBOL(pci_match_id); EXPORT_SYMBOL(__pci_register_driver); diff --git a/libdde_linux26/lib/src/drivers/pci/pci.c b/libdde_linux26/lib/src/drivers/pci/pci.c index 9bf601c3..f67bf734 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci.c +++ b/libdde_linux26/lib/src/drivers/pci/pci.c @@ -2404,7 +2404,7 @@ int __devinit pci_init(void) return 0; } -int __init pci_setup(char *str) +static int __init pci_setup(char *str) { #ifndef DDE_LINUX while (str) { @@ -2434,7 +2434,7 @@ int __init pci_setup(char *str) } early_param("pci", pci_setup); -//device_initcall(pci_init); +device_initcall(pci_init); EXPORT_SYMBOL(pci_reenable_device); EXPORT_SYMBOL(pci_enable_device_io); diff --git a/libdde_linux26/lib/src/drivers/pci/probe.c b/libdde_linux26/lib/src/drivers/pci/probe.c index 9cbc3bfb..32da5108 100644 --- a/libdde_linux26/lib/src/drivers/pci/probe.c +++ b/libdde_linux26/lib/src/drivers/pci/probe.c @@ -100,11 +100,11 @@ static struct class pcibus_class = { .dev_release = &release_pcibus_dev, }; -int __init pcibus_class_init(void) +static int __init pcibus_class_init(void) { return class_register(&pcibus_class); } -//postcore_initcall(pcibus_class_init); +postcore_initcall(pcibus_class_init); /* * Translate the low bits of the PCI base diff --git a/libdde_linux26/lib/src/fs/char_dev.c b/libdde_linux26/lib/src/fs/char_dev.c index 9dd832b4..3b8e8b3d 100644 --- a/libdde_linux26/lib/src/fs/char_dev.c +++ b/libdde_linux26/lib/src/fs/char_dev.c @@ -556,7 +556,7 @@ void __init chrdev_init(void) } #ifndef LIBINPUT -//core_initcall(chrdev_init); +core_initcall(chrdev_init); #endif /* Let modules do char dev stuff */ diff --git a/libdde_linux26/lib/src/kernel/workqueue.c b/libdde_linux26/lib/src/kernel/workqueue.c index d52b22b5..5ad26d9f 100644 --- a/libdde_linux26/lib/src/kernel/workqueue.c +++ b/libdde_linux26/lib/src/kernel/workqueue.c @@ -1034,5 +1034,5 @@ void __init init_workqueues(void) } #ifdef DDE_LINUX -//core_initcall(init_workqueues); +core_initcall(init_workqueues); #endif diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index b1307dd2..65b4ba42 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -5186,7 +5186,7 @@ static struct pernet_operations __net_initdata default_device_ops = { * This is called single threaded during boot, so no need * to take the rtnl semaphore. */ -int __init net_dev_init(void) +static int __init net_dev_init(void) { int i, rc = -ENOMEM; @@ -5254,7 +5254,7 @@ out: return rc; } -//subsys_initcall(net_dev_init); +subsys_initcall(net_dev_init); EXPORT_SYMBOL(__dev_get_by_index); EXPORT_SYMBOL(__dev_get_by_name); diff --git a/libdde_linux26/lib/src/net/core/net_namespace.c b/libdde_linux26/lib/src/net/core/net_namespace.c index 29f29621..ab5a0a7f 100644 --- a/libdde_linux26/lib/src/net/core/net_namespace.c +++ b/libdde_linux26/lib/src/net/core/net_namespace.c @@ -202,7 +202,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) } #endif -int __init net_ns_init(void) +static int __init net_ns_init(void) { struct net_generic *ng; int err; @@ -239,7 +239,7 @@ int __init net_ns_init(void) return 0; } -//pure_initcall(net_ns_init); +pure_initcall(net_ns_init); #ifdef CONFIG_NET_NS static int register_pernet_operations(struct list_head *list, -- cgit v1.2.3 From 2b91d7ba805279f3f871f95d5d49c6c1b7d6b879 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Mon, 12 Jul 2010 09:47:31 +0200 Subject: Use Linux's udelay and ndelay. It's not very precise to implement udelay and ndelay with loops in the user space, but should be enough. --- libdde_linux26/lib/src/Makefile | 2 + libdde_linux26/lib/src/arch/l4/timer.c | 19 --- libdde_linux26/lib/src/arch/x86/lib/delay.c | 138 +++++++++++++++++++++ libdde_linux26/lib/src/init/calibrate.c | 182 ++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+), 19 deletions(-) create mode 100644 libdde_linux26/lib/src/arch/x86/lib/delay.c create mode 100644 libdde_linux26/lib/src/init/calibrate.c (limited to 'libdde_linux26/lib/src/arch/l4/timer.c') diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile index ed53fdeb..358196bb 100644 --- a/libdde_linux26/lib/src/Makefile +++ b/libdde_linux26/lib/src/Makefile @@ -58,6 +58,7 @@ SRC_C_libdde_linux26.o.a = $(addprefix arch/l4/, $(SRC_DDE)) ifeq ($(ARCH), x86) SRC_S_libdde_linux26.o.a += $(ARCH_DIR)/lib/semaphore_32.S +SRC_S_libdde_linux26.o.a += $(ARCH_DIR)/lib/delay.o SRC_C_libdde_linux26.o.a += lib/rwsem.c SRC_C_libdde_linux26.o.a += $(ARCH_DIR)/kernel/pci-dma.c SRC_C_libdde_linux26.o.a += $(ARCH_DIR)/kernel/pci-nommu.c @@ -120,6 +121,7 @@ SRC_C_libdde_linux26.o.a += \ lib/string.c \ lib/vsprintf.c \ lib/rbtree.c \ + init/calibrate.c \ mm/dmapool.c \ mm/mempool.c \ mm/swap.c \ diff --git a/libdde_linux26/lib/src/arch/l4/timer.c b/libdde_linux26/lib/src/arch/l4/timer.c index 2b657ab4..b85c83a9 100644 --- a/libdde_linux26/lib/src/arch/l4/timer.c +++ b/libdde_linux26/lib/src/arch/l4/timer.c @@ -126,25 +126,6 @@ void msleep(unsigned int msecs) ddekit_thread_msleep(msecs); } - -void __const_udelay(unsigned long xloops) -{ - ddekit_thread_usleep(xloops); -} - - -void __udelay(unsigned long usecs) -{ - ddekit_thread_usleep(usecs); -} - - -void __ndelay(unsigned long nsecs) -{ - ddekit_thread_nsleep(nsecs); -} - - void __init l4dde26_init_timers(void) { ddekit_init_timers(); diff --git a/libdde_linux26/lib/src/arch/x86/lib/delay.c b/libdde_linux26/lib/src/arch/x86/lib/delay.c new file mode 100644 index 00000000..6097c6bb --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/delay.c @@ -0,0 +1,138 @@ +/* + * Precise Delay Loops for i386 + * + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1997 Martin Mares + * Copyright (C) 2008 Jiri Hladky + * + * The __delay function must _NOT_ be inlined as its execution time + * depends wildly on alignment on many x86 processors. The additional + * jump magic is needed to get the timing stable on all the CPU's + * we have to worry about. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_SMP +# include +#endif +#include + +/* simple loop based delay: */ +static void delay_loop(unsigned long loops) +{ + asm volatile( + " test %0,%0 \n" + " jz 3f \n" + " jmp 1f \n" + + ".align 16 \n" + "1: jmp 2f \n" + + ".align 16 \n" + "2: dec %0 \n" + " jnz 2b \n" + "3: dec %0 \n" + + : /* we don't need output */ + :"a" (loops) + ); +} + +/* TSC based delay: */ +static void delay_tsc(unsigned long loops) +{ + unsigned long bclock, now; + int cpu; + + preempt_disable(); + cpu = smp_processor_id(); + rdtscl(bclock); + for (;;) { + rdtscl(now); + if ((now - bclock) >= loops) + break; + + /* Allow RT tasks to run */ + preempt_enable(); + rep_nop(); + preempt_disable(); + + /* + * It is possible that we moved to another CPU, and + * since TSC's are per-cpu we need to calculate + * that. The delay must guarantee that we wait "at + * least" the amount of time. Being moved to another + * CPU could make the wait longer but we just need to + * make sure we waited long enough. Rebalance the + * counter for this CPU. + */ + if (unlikely(cpu != smp_processor_id())) { + loops -= (now - bclock); + cpu = smp_processor_id(); + rdtscl(bclock); + } + } + preempt_enable(); +} + +/* + * Since we calibrate only once at boot, this + * function should be set once at boot and not changed + */ +static void (*delay_fn)(unsigned long) = delay_loop; + +void use_tsc_delay(void) +{ + delay_fn = delay_tsc; +} + +int __devinit read_current_timer(unsigned long *timer_val) +{ + if (delay_fn == delay_tsc) { + rdtscll(*timer_val); + return 0; + } + return -1; +} + +void __delay(unsigned long loops) +{ + delay_fn(loops); +} +EXPORT_SYMBOL(__delay); + +inline void __const_udelay(unsigned long xloops) +{ + int d0; + + xloops *= 4; + asm("mull %%edx" + :"=d" (xloops), "=&a" (d0) + :"1" (xloops), "0" + (loops_per_jiffy * (HZ/4))); + + __delay(++xloops); +} +EXPORT_SYMBOL(__const_udelay); + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ +} +EXPORT_SYMBOL(__udelay); + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ +} +EXPORT_SYMBOL(__ndelay); diff --git a/libdde_linux26/lib/src/init/calibrate.c b/libdde_linux26/lib/src/init/calibrate.c new file mode 100644 index 00000000..aede8e53 --- /dev/null +++ b/libdde_linux26/lib/src/init/calibrate.c @@ -0,0 +1,182 @@ +/* calibrate.c: default delay calibration + * + * Excised from init/main.c + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include + +unsigned long loops_per_jiffy = (1<<12); +EXPORT_SYMBOL(loops_per_jiffy); + +unsigned long lpj_fine; +unsigned long preset_lpj; +static int __init lpj_setup(char *str) +{ + preset_lpj = simple_strtoul(str,NULL,0); + return 1; +} + +__setup("lpj=", lpj_setup); + +#ifdef ARCH_HAS_READ_CURRENT_TIMER + +/* This routine uses the read_current_timer() routine and gets the + * loops per jiffy directly, instead of guessing it using delay(). + * Also, this code tries to handle non-maskable asynchronous events + * (like SMIs) + */ +#define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100)) +#define MAX_DIRECT_CALIBRATION_RETRIES 5 + +static unsigned long __cpuinit calibrate_delay_direct(void) +{ + unsigned long pre_start, start, post_start; + unsigned long pre_end, end, post_end; + unsigned long start_jiffies; + unsigned long timer_rate_min, timer_rate_max; + unsigned long good_timer_sum = 0; + unsigned long good_timer_count = 0; + int i; + + if (read_current_timer(&pre_start) < 0 ) + return 0; + + /* + * A simple loop like + * while ( jiffies < start_jiffies+1) + * start = read_current_timer(); + * will not do. As we don't really know whether jiffy switch + * happened first or timer_value was read first. And some asynchronous + * event can happen between these two events introducing errors in lpj. + * + * So, we do + * 1. pre_start <- When we are sure that jiffy switch hasn't happened + * 2. check jiffy switch + * 3. start <- timer value before or after jiffy switch + * 4. post_start <- When we are sure that jiffy switch has happened + * + * Note, we don't know anything about order of 2 and 3. + * Now, by looking at post_start and pre_start difference, we can + * check whether any asynchronous event happened or not + */ + + for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) { + pre_start = 0; + read_current_timer(&start); + start_jiffies = jiffies; + while (jiffies <= (start_jiffies + 1)) { + pre_start = start; + read_current_timer(&start); + } + read_current_timer(&post_start); + + pre_end = 0; + end = post_start; + while (jiffies <= + (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) { + pre_end = end; + read_current_timer(&end); + } + read_current_timer(&post_end); + + timer_rate_max = (post_end - pre_start) / + DELAY_CALIBRATION_TICKS; + timer_rate_min = (pre_end - post_start) / + DELAY_CALIBRATION_TICKS; + + /* + * If the upper limit and lower limit of the timer_rate is + * >= 12.5% apart, redo calibration. + */ + if (pre_start != 0 && pre_end != 0 && + (timer_rate_max - timer_rate_min) < (timer_rate_max >> 3)) { + good_timer_count++; + good_timer_sum += timer_rate_max; + } + } + + if (good_timer_count) + return (good_timer_sum/good_timer_count); + + printk(KERN_WARNING "calibrate_delay_direct() failed to get a good " + "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n"); + return 0; +} +#else +static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} +#endif + +/* + * This is the number of bits of precision for the loops_per_jiffy. Each + * bit takes on average 1.5/HZ seconds. This (like the original) is a little + * better than 1% + * For the boot cpu we can skip the delay calibration and assign it a value + * calculated based on the timer frequency. + * For the rest of the CPUs we cannot assume that the timer frequency is same as + * the cpu frequency, hence do the calibration for those. + */ +#define LPS_PREC 8 + +void __cpuinit calibrate_delay(void) +{ + unsigned long ticks, loopbit; + int lps_precision = LPS_PREC; + + if (preset_lpj) { + loops_per_jiffy = preset_lpj; + printk(KERN_INFO + "Calibrating delay loop (skipped) preset value.. "); + } else if ((smp_processor_id() == 0) && lpj_fine) { + loops_per_jiffy = lpj_fine; + printk(KERN_INFO + "Calibrating delay loop (skipped), " + "value calculated using timer frequency.. "); + } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) { + printk(KERN_INFO + "Calibrating delay using timer specific routine.. "); + } else { + loops_per_jiffy = (1<<12); + + printk(KERN_INFO "Calibrating delay loop... "); + while ((loops_per_jiffy <<= 1) != 0) { + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + /* Go .. */ + ticks = jiffies; + __delay(loops_per_jiffy); + ticks = jiffies - ticks; + if (ticks) + break; + } + + /* + * Do a binary approximation to get loops_per_jiffy set to + * equal one clock (up to lps_precision bits) + */ + loops_per_jiffy >>= 1; + loopbit = loops_per_jiffy; + while (lps_precision-- && (loopbit >>= 1)) { + loops_per_jiffy |= loopbit; + ticks = jiffies; + while (ticks == jiffies) + /* nothing */; + ticks = jiffies; + __delay(loops_per_jiffy); + if (jiffies != ticks) /* longer than 1 tick */ + loops_per_jiffy &= ~loopbit; + } + } + printk(KERN_CONT "%lu.%02lu BogoMIPS (lpj=%lu)\n", + loops_per_jiffy/(500000/HZ), + (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); +} + +core_initcall(calibrate_delay); -- cgit v1.2.3