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/.svn/all-wcprops | 5 + libdde_linux26/lib/src/arch/.svn/entries | 34 + libdde_linux26/lib/src/arch/.svn/format | 1 + libdde_linux26/lib/src/arch/l4/.svn/all-wcprops | 155 ++++ libdde_linux26/lib/src/arch/l4/.svn/entries | 878 +++++++++++++++++++++ libdde_linux26/lib/src/arch/l4/.svn/format | 1 + .../src/arch/l4/.svn/text-base/cli_sti.c.svn-base | 66 ++ .../lib/src/arch/l4/.svn/text-base/fs.c.svn-base | 111 +++ .../arch/l4/.svn/text-base/hw-helpers.c.svn-base | 12 + .../lib/src/arch/l4/.svn/text-base/init.c.svn-base | 33 + .../arch/l4/.svn/text-base/init_task.c.svn-base | 131 +++ .../src/arch/l4/.svn/text-base/inodes.c.svn-base | 311 ++++++++ .../lib/src/arch/l4/.svn/text-base/irq.c.svn-base | 247 ++++++ .../src/arch/l4/.svn/text-base/kmalloc.c.svn-base | 199 +++++ .../arch/l4/.svn/text-base/kmem_cache.c.svn-base | 213 +++++ .../src/arch/l4/.svn/text-base/local.h.svn-base | 99 +++ .../arch/l4/.svn/text-base/mm-helper.c.svn-base | 45 ++ .../lib/src/arch/l4/.svn/text-base/net.c.svn-base | 36 + .../arch/l4/.svn/text-base/page_alloc.c.svn-base | 281 +++++++ .../src/arch/l4/.svn/text-base/param.c.svn-base | 32 + .../lib/src/arch/l4/.svn/text-base/pci.c.svn-base | 189 +++++ .../src/arch/l4/.svn/text-base/power.c.svn-base | 23 + .../src/arch/l4/.svn/text-base/process.c.svn-base | 347 ++++++++ .../lib/src/arch/l4/.svn/text-base/res.c.svn-base | 180 +++++ .../src/arch/l4/.svn/text-base/sched.c.svn-base | 155 ++++ .../src/arch/l4/.svn/text-base/signal.c.svn-base | 24 + .../lib/src/arch/l4/.svn/text-base/smp.c.svn-base | 37 + .../src/arch/l4/.svn/text-base/softirq.c.svn-base | 267 +++++++ .../src/arch/l4/.svn/text-base/timer.c.svn-base | 184 +++++ .../src/arch/l4/.svn/text-base/vmalloc.c.svn-base | 30 + .../src/arch/l4/.svn/text-base/vmstat.c.svn-base | 34 + libdde_linux26/lib/src/arch/l4/cli_sti.c | 66 ++ libdde_linux26/lib/src/arch/l4/fs.c | 111 +++ libdde_linux26/lib/src/arch/l4/hw-helpers.c | 12 + libdde_linux26/lib/src/arch/l4/init.c | 33 + libdde_linux26/lib/src/arch/l4/init_task.c | 131 +++ libdde_linux26/lib/src/arch/l4/inodes.c | 311 ++++++++ libdde_linux26/lib/src/arch/l4/irq.c | 247 ++++++ libdde_linux26/lib/src/arch/l4/kmalloc.c | 199 +++++ libdde_linux26/lib/src/arch/l4/kmem_cache.c | 213 +++++ libdde_linux26/lib/src/arch/l4/local.h | 99 +++ libdde_linux26/lib/src/arch/l4/mm-helper.c | 45 ++ libdde_linux26/lib/src/arch/l4/net.c | 36 + libdde_linux26/lib/src/arch/l4/page_alloc.c | 281 +++++++ libdde_linux26/lib/src/arch/l4/param.c | 32 + libdde_linux26/lib/src/arch/l4/pci.c | 189 +++++ libdde_linux26/lib/src/arch/l4/power.c | 23 + libdde_linux26/lib/src/arch/l4/process.c | 347 ++++++++ libdde_linux26/lib/src/arch/l4/res.c | 180 +++++ libdde_linux26/lib/src/arch/l4/sched.c | 155 ++++ libdde_linux26/lib/src/arch/l4/signal.c | 24 + libdde_linux26/lib/src/arch/l4/smp.c | 37 + libdde_linux26/lib/src/arch/l4/softirq.c | 267 +++++++ libdde_linux26/lib/src/arch/l4/timer.c | 184 +++++ libdde_linux26/lib/src/arch/l4/vmalloc.c | 30 + libdde_linux26/lib/src/arch/l4/vmstat.c | 34 + libdde_linux26/lib/src/arch/x86/.svn/all-wcprops | 5 + libdde_linux26/lib/src/arch/x86/.svn/entries | 31 + libdde_linux26/lib/src/arch/x86/.svn/format | 1 + .../lib/src/arch/x86/lib/.svn/all-wcprops | 11 + libdde_linux26/lib/src/arch/x86/lib/.svn/entries | 62 ++ libdde_linux26/lib/src/arch/x86/lib/.svn/format | 1 + .../x86/lib/.svn/text-base/semaphore_32.S.svn-base | 138 ++++ libdde_linux26/lib/src/arch/x86/lib/semaphore_32.S | 138 ++++ 64 files changed, 8033 insertions(+) create mode 100644 libdde_linux26/lib/src/arch/.svn/all-wcprops create mode 100644 libdde_linux26/lib/src/arch/.svn/entries create mode 100644 libdde_linux26/lib/src/arch/.svn/format create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/all-wcprops create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/entries create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/format create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/cli_sti.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/fs.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/hw-helpers.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/init.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/init_task.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/inodes.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/irq.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/kmalloc.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/kmem_cache.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/local.h.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/mm-helper.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/net.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/page_alloc.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/param.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/pci.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/power.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/process.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/res.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/sched.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/signal.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/smp.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/softirq.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/timer.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/vmalloc.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/.svn/text-base/vmstat.c.svn-base create mode 100644 libdde_linux26/lib/src/arch/l4/cli_sti.c create mode 100644 libdde_linux26/lib/src/arch/l4/fs.c create mode 100644 libdde_linux26/lib/src/arch/l4/hw-helpers.c create mode 100644 libdde_linux26/lib/src/arch/l4/init.c create mode 100644 libdde_linux26/lib/src/arch/l4/init_task.c create mode 100644 libdde_linux26/lib/src/arch/l4/inodes.c create mode 100644 libdde_linux26/lib/src/arch/l4/irq.c create mode 100644 libdde_linux26/lib/src/arch/l4/kmalloc.c create mode 100644 libdde_linux26/lib/src/arch/l4/kmem_cache.c create mode 100644 libdde_linux26/lib/src/arch/l4/local.h create mode 100644 libdde_linux26/lib/src/arch/l4/mm-helper.c create mode 100644 libdde_linux26/lib/src/arch/l4/net.c create mode 100644 libdde_linux26/lib/src/arch/l4/page_alloc.c create mode 100644 libdde_linux26/lib/src/arch/l4/param.c create mode 100644 libdde_linux26/lib/src/arch/l4/pci.c create mode 100644 libdde_linux26/lib/src/arch/l4/power.c create mode 100644 libdde_linux26/lib/src/arch/l4/process.c create mode 100644 libdde_linux26/lib/src/arch/l4/res.c create mode 100644 libdde_linux26/lib/src/arch/l4/sched.c create mode 100644 libdde_linux26/lib/src/arch/l4/signal.c create mode 100644 libdde_linux26/lib/src/arch/l4/smp.c create mode 100644 libdde_linux26/lib/src/arch/l4/softirq.c create mode 100644 libdde_linux26/lib/src/arch/l4/timer.c create mode 100644 libdde_linux26/lib/src/arch/l4/vmalloc.c create mode 100644 libdde_linux26/lib/src/arch/l4/vmstat.c create mode 100644 libdde_linux26/lib/src/arch/x86/.svn/all-wcprops create mode 100644 libdde_linux26/lib/src/arch/x86/.svn/entries create mode 100644 libdde_linux26/lib/src/arch/x86/.svn/format create mode 100644 libdde_linux26/lib/src/arch/x86/lib/.svn/all-wcprops create mode 100644 libdde_linux26/lib/src/arch/x86/lib/.svn/entries create mode 100644 libdde_linux26/lib/src/arch/x86/lib/.svn/format create mode 100644 libdde_linux26/lib/src/arch/x86/lib/.svn/text-base/semaphore_32.S.svn-base create mode 100644 libdde_linux26/lib/src/arch/x86/lib/semaphore_32.S (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/.svn/all-wcprops b/libdde_linux26/lib/src/arch/.svn/all-wcprops new file mode 100644 index 00000000..775206bc --- /dev/null +++ b/libdde_linux26/lib/src/arch/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 63 +/repos/tudos/!svn/ver/457/trunk/l4/pkg/dde/linux26/lib/src/arch +END diff --git a/libdde_linux26/lib/src/arch/.svn/entries b/libdde_linux26/lib/src/arch/.svn/entries new file mode 100644 index 00000000..b075adca --- /dev/null +++ b/libdde_linux26/lib/src/arch/.svn/entries @@ -0,0 +1,34 @@ +9 + +dir +465 +http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/lib/src/arch +http://svn.tudos.org/repos/tudos + + + +2009-05-23T02:50:17.774710Z +457 +l4check + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +a704ac0b-3a55-4d43-a2a9-7be6f07c34fb + +l4 +dir + +x86 +dir + diff --git a/libdde_linux26/lib/src/arch/.svn/format b/libdde_linux26/lib/src/arch/.svn/format new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/libdde_linux26/lib/src/arch/.svn/format @@ -0,0 +1 @@ +9 diff --git a/libdde_linux26/lib/src/arch/l4/.svn/all-wcprops b/libdde_linux26/lib/src/arch/l4/.svn/all-wcprops new file mode 100644 index 00000000..132337d1 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/all-wcprops @@ -0,0 +1,155 @@ +K 25 +svn:wc:ra_dav:version-url +V 66 +/repos/tudos/!svn/ver/457/trunk/l4/pkg/dde/linux26/lib/src/arch/l4 +END +local.h +K 25 +svn:wc:ra_dav:version-url +V 74 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/local.h +END +smp.c +K 25 +svn:wc:ra_dav:version-url +V 72 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/smp.c +END +param.c +K 25 +svn:wc:ra_dav:version-url +V 74 +/repos/tudos/!svn/ver/240/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/param.c +END +init.c +K 25 +svn:wc:ra_dav:version-url +V 73 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/init.c +END +fs.c +K 25 +svn:wc:ra_dav:version-url +V 71 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/fs.c +END +pci.c +K 25 +svn:wc:ra_dav:version-url +V 72 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/pci.c +END +kmem_cache.c +K 25 +svn:wc:ra_dav:version-url +V 79 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/kmem_cache.c +END +signal.c +K 25 +svn:wc:ra_dav:version-url +V 75 +/repos/tudos/!svn/ver/174/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/signal.c +END +hw-helpers.c +K 25 +svn:wc:ra_dav:version-url +V 79 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/hw-helpers.c +END +process.c +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/process.c +END +vmstat.c +K 25 +svn:wc:ra_dav:version-url +V 75 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/vmstat.c +END +timer.c +K 25 +svn:wc:ra_dav:version-url +V 74 +/repos/tudos/!svn/ver/457/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/timer.c +END +inodes.c +K 25 +svn:wc:ra_dav:version-url +V 75 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/inodes.c +END +kmalloc.c +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/kmalloc.c +END +init_task.c +K 25 +svn:wc:ra_dav:version-url +V 78 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/init_task.c +END +page_alloc.c +K 25 +svn:wc:ra_dav:version-url +V 79 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/page_alloc.c +END +net.c +K 25 +svn:wc:ra_dav:version-url +V 72 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/net.c +END +mm-helper.c +K 25 +svn:wc:ra_dav:version-url +V 78 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/mm-helper.c +END +cli_sti.c +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/cli_sti.c +END +sched.c +K 25 +svn:wc:ra_dav:version-url +V 74 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/sched.c +END +softirq.c +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/softirq.c +END +res.c +K 25 +svn:wc:ra_dav:version-url +V 72 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/res.c +END +irq.c +K 25 +svn:wc:ra_dav:version-url +V 72 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/irq.c +END +power.c +K 25 +svn:wc:ra_dav:version-url +V 74 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/power.c +END +vmalloc.c +K 25 +svn:wc:ra_dav:version-url +V 76 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/l4/vmalloc.c +END diff --git a/libdde_linux26/lib/src/arch/l4/.svn/entries b/libdde_linux26/lib/src/arch/l4/.svn/entries new file mode 100644 index 00000000..a4e08f01 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/entries @@ -0,0 +1,878 @@ +9 + +dir +465 +http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/lib/src/arch/l4 +http://svn.tudos.org/repos/tudos + + + +2009-05-23T02:50:17.774710Z +457 +l4check + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +a704ac0b-3a55-4d43-a2a9-7be6f07c34fb + +local.h +file + + + + +2009-11-15T17:17:12.000000Z +29e4e373a5332517fa8d3a54b63a934c +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +3155 + +smp.c +file + + + + +2009-11-15T17:17:12.000000Z +0baa40739f76a596efe1d2ef99768f59 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1294 + +param.c +file + + + + +2009-11-15T17:17:12.000000Z +8b9465dfae207ca0ce9548228914b19f +2007-11-27T03:55:44.347675Z +240 +l4check + + + + + + + + + + + + + + + + + + + + + +1039 + +init.c +file + + + + +2009-11-15T17:17:12.000000Z +c59f682047dbf216f271ba4fb8f962ef +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +713 + +fs.c +file + + + + +2009-11-15T17:17:12.000000Z +361eeaac7be43ebe64478812bdf3808a +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +2353 + +pci.c +file + + + + +2009-11-15T17:17:12.000000Z +670757aeca81d5fdbcce07c45902b2f4 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4732 + +kmem_cache.c +file + + + + +2009-11-15T17:17:12.000000Z +1d7b5540f6113539b83f4688eb5a320d +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +5429 + +signal.c +file + + + + +2009-11-15T17:17:12.000000Z +1c1133b1a3dcf504174b892eba60986a +2007-09-08T19:44:13.897747Z +174 +l4check + + + + + + + + + + + + + + + + + + + + + +875 + +hw-helpers.c +file + + + + +2009-11-15T17:17:12.000000Z +7900d76d82fab85c74b0d8baec1baac5 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +170 + +process.c +file + + + + +2009-11-15T17:17:12.000000Z +e256217d715b25cf56bb937480c82376 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +9859 + +vmstat.c +file + + + + +2009-11-15T17:17:12.000000Z +3f706a9a494cf0bfd99facee793dd0d5 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +608 + +timer.c +file + + + + +2009-11-15T17:17:12.000000Z +f13640bc9b9d4520e7b8ec09d3b9e452 +2009-05-23T02:50:17.774710Z +457 +l4check + + + + + + + + + + + + + + + + + + + + + +3669 + +inodes.c +file + + + + +2009-11-15T17:17:12.000000Z +8f1f06ea530105b7b1b1b24fd0cb5d00 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +6687 + +kmalloc.c +file + + + + +2009-11-15T17:17:12.000000Z +2fd70eccfddd108357815aa4bb031354 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4327 + +init_task.c +file + + + + +2009-11-15T17:17:12.000000Z +fc20d990328c12f596b836e722781f63 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +3360 + +page_alloc.c +file + + + + +2009-11-15T17:17:12.000000Z +584a5941cdf1efe2435718993a980ba1 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +6768 + +net.c +file + + + + +2009-11-15T17:17:12.000000Z +2adc371a98f0fd8fae363e0f70854314 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1307 + +mm-helper.c +file + + + + +2009-11-15T17:17:12.000000Z +4b1d4ac41bb0a6ffb8c9bbe6f1ab95b1 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +880 + +cli_sti.c +file + + + + +2009-11-15T17:17:12.000000Z +8732f061e7ff7d24c42fb8dc9aec718f +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +1284 + +sched.c +file + + + + +2009-11-15T17:17:12.000000Z +904a23f9a1efa20b904b9294e5c3fe43 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +3206 + +softirq.c +file + + + + +2009-11-15T17:17:12.000000Z +7564de83f9ac6f983ff7e8346c78bba8 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +5778 + +res.c +file + + + + +2009-11-15T17:17:12.000000Z +9190bb75985ff0ee2135c7ae47a7800d +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +4275 + +irq.c +file + + + + +2009-11-15T17:17:12.000000Z +19e10dde42bbbe5176338d96ae8553ba +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +5607 + +power.c +file + + + + +2009-11-15T17:17:12.000000Z +c108e3ad0b0c0c68015fed4e159c1b53 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +642 + +vmalloc.c +file + + + + +2009-11-15T17:17:12.000000Z +73cceaf52046b2f0d152ad8cfde1685f +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +919 + diff --git a/libdde_linux26/lib/src/arch/l4/.svn/format b/libdde_linux26/lib/src/arch/l4/.svn/format new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/format @@ -0,0 +1 @@ +9 diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/cli_sti.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/cli_sti.c.svn-base new file mode 100644 index 00000000..81c4feea --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/cli_sti.c.svn-base @@ -0,0 +1,66 @@ +#include "local.h" + +#include + +/* IRQ lock reference counter */ +static atomic_t _refcnt = ATOMIC_INIT(0); + +/* Check whether IRQs are currently disabled. + * + * This is the case, if flags is greater than 0. + */ + +int raw_irqs_disabled_flags(unsigned long flags) +{ + return ((int)flags > 0); +} + +/* Store the current flags state. + * + * This is done by returning the current refcnt. + * + * XXX: Up to now, flags was always 0 at this point and + * I assume that this is always the case. Prove? + */ +unsigned long __raw_local_save_flags(void) +{ + return (unsigned long)atomic_read(&_refcnt); +} + +/* Restore IRQ state. */ +void raw_local_irq_restore(unsigned long flags) +{ + atomic_set(&_refcnt, flags); +} + +/* Disable IRQs by grabbing the IRQ lock. */ +void raw_local_irq_disable(void) +{ + atomic_inc(&_refcnt); +} + +/* Unlock the IRQ lock until refcnt is 0. */ +void raw_local_irq_enable(void) +{ + atomic_set(&_refcnt, 0); +} + + +void raw_safe_halt(void) +{ + WARN_UNIMPL; +} + + +void halt(void) +{ + WARN_UNIMPL; +} + +/* These functions are empty for DDE. Every DDE thread is a separate + * "virtual" CPU. Therefore there is no need to en/disable bottom halves. + */ +void local_bh_disable(void) {} +void __local_bh_enable(void) {} +void _local_bh_enable(void) {} +void local_bh_enable(void) {} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/fs.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/fs.c.svn-base new file mode 100644 index 00000000..db452949 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/fs.c.svn-base @@ -0,0 +1,111 @@ +#include "local.h" + +#include +#include +#include + +/* + * Some subsystems, such as the blockdev layer, implement their data + * hierarchy as a pseudo file system. To not incorporate the complete + * Linux VFS implementation, we cut this down to an own one only for + * pseudo file systems. + */ +static LIST_HEAD(dde_vfs_mounts); + +#define MAX_RA_PAGES 1 + +void default_unplug_io_fn(struct backing_dev_info *bdi, struct page* p) +{ +} + +struct backing_dev_info default_backing_dev_info = { + .ra_pages = MAX_RA_PAGES, + .state = 0, + .capabilities = BDI_CAP_MAP_COPY, + .unplug_io_fn = default_unplug_io_fn, +}; + +int seq_printf(struct seq_file *m, const char *f, ...) +{ + WARN_UNIMPL; + return 0; +} + +int generic_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + WARN_UNIMPL; + return 0; +} + + +/************************************** + * Filemap stuff * + **************************************/ +struct page * find_get_page(struct address_space *mapping, unsigned long offset) +{ + WARN_UNIMPL; + return NULL; +} + +void unlock_page(struct page *page) +{ + WARN_UNIMPL; +} + +int test_set_page_writeback(struct page *page) +{ + WARN_UNIMPL; + return 0; +} + +void end_page_writeback(struct page *page) +{ + WARN_UNIMPL; +} + +void do_invalidatepage(struct page *page, unsigned long offset) +{ + WARN_UNIMPL; +} + +int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page) +{ + WARN_UNIMPL; + return 0; +} + +static struct vfsmount *dde_kern_mount(struct file_system_type *type, + int flags, const char *name, + void *data) +{ + struct list_head *pos, *head; + int error; + + head = &dde_vfs_mounts; + __list_for_each(pos, head) { + struct vfsmount *mnt = list_entry(pos, struct vfsmount, next); + if (strcmp(name, mnt->name) == 0) { + printk("FS type %s already mounted!?\n", name); + BUG(); + return NULL; + } + } + + struct vfsmount *m = kzalloc(sizeof(*m), GFP_KERNEL); + m->fs_type = type; + m->name = kmalloc(strlen(name) + 1, GFP_KERNEL); + memcpy(m->name, name, strlen(name) + 1); + + error = type->get_sb(type, flags, name, data, m); + BUG_ON(error); + + list_add_tail(&m->next, &dde_vfs_mounts); + + return m; +} + +struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) +{ + return dde_kern_mount(type, 0, type->name, NULL); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/hw-helpers.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/hw-helpers.c.svn-base new file mode 100644 index 00000000..555406c9 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/hw-helpers.c.svn-base @@ -0,0 +1,12 @@ +#include "local.h" + +#include + +note_buf_t *crash_notes = NULL; + +void touch_nmi_watchdog(void) +{ + WARN_UNIMPL; +} + +unsigned long pci_mem_start = 0xABCDABCD; diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/init.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/init.c.svn-base new file mode 100644 index 00000000..e89ef27f --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/init.c.svn-base @@ -0,0 +1,33 @@ +#include "local.h" + +#include +#include + +#define DEBUG_PCI(msg, ...) ddekit_printf( "\033[33m"msg"\033[0m\n", ##__VA_ARGS__) + +/* Didn't know where to put this. */ +unsigned long __per_cpu_offset[NR_CPUS]; + +extern void driver_init(void); +extern int classes_init(void); + +void __init __attribute__((used)) l4dde26_init(void) +{ + /* first, initialize DDEKit */ + ddekit_init(); + + l4dde26_kmalloc_init(); + + /* Init Linux driver framework before trying to add PCI devs to the bus */ + driver_init(); + + printk("Initialized DDELinux 2.6\n"); +} + +void l4dde26_do_initcalls(void) +{ + /* finally, let DDEKit perform all the initcalls */ + ddekit_do_initcalls(); +} + +dde_initcall(l4dde26_init); diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/init_task.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/init_task.c.svn-base new file mode 100644 index 00000000..685373d1 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/init_task.c.svn-base @@ -0,0 +1,131 @@ +#include "local.h" + +//#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* init task */ +struct task_struct init_task; + +/* From kernel/pid.c */ +#define BITS_PER_PAGE (PAGE_SIZE*8) +#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) + +/* From init/main.c */ +enum system_states system_state; +EXPORT_SYMBOL(system_state); + +struct fs_struct init_fs = { + .count = ATOMIC_INIT(1), + .lock = __RW_LOCK_UNLOCKED(init_fs.lock), + .umask = 0022, +}; + +struct files_struct init_files = { + .count = ATOMIC_INIT(1), + .fdt = &init_files.fdtab, + .fdtab = { + .max_fds = NR_OPEN_DEFAULT, + .fd = &init_files.fd_array[0], + .close_on_exec = (fd_set *)&init_files.close_on_exec_init, + .open_fds = (fd_set *)&init_files.open_fds_init, + .rcu = RCU_HEAD_INIT, + }, + .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), +}; + +struct signal_struct init_signals = INIT_SIGNALS(init_signals); +struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); +pgd_t swapper_pg_dir[PTRS_PER_PGD]; +union thread_union init_thread_union = { INIT_THREAD_INFO(init_task) }; +struct group_info init_groups = {.usage = ATOMIC_INIT(2)}; + +struct user_struct root_user = { + .__count = ATOMIC_INIT(1), + .processes = ATOMIC_INIT(1), + .files = ATOMIC_INIT(0), + .sigpending = ATOMIC_INIT(0), + .mq_bytes = 0, + .locked_shm = 0, +}; + +/* + * PID-map pages start out as NULL, they get allocated upon + * first use and are never deallocated. This way a low pid_max + * value does not cause lots of bitmaps to be allocated, but + * the scheme scales to up to 4 million PIDs, runtime. + */ +struct pid_namespace init_pid_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, + .pidmap = { + [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } + }, + .last_pid = 0, + .level = 0, + .child_reaper = &init_task, +}; +EXPORT_SYMBOL_GPL(init_pid_ns); + +struct net init_net __attribute__((weak)); + +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); + +struct ipc_namespace init_ipc_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, +}; + +struct user_namespace init_user_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, +}; + + +struct uts_namespace init_uts_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, + .name = { + .sysname = "L4/DDE", + .nodename = "", + .release = "2.6", + .version = "25", + .machine = "", + .domainname = "", + }, +}; + +struct exec_domain default_exec_domain = { + .name = "Linux", /* name */ + .handler = NULL, /* no signaling! */ + .pers_low = 0, /* PER_LINUX personality. */ + .pers_high = 0, /* PER_LINUX personality. */ + .signal_map = 0, /* Identity map signals. */ + .signal_invmap = 0, /* - both ways. */ +}; + +/* copy of the initial task struct */ +struct task_struct init_task = INIT_TASK(init_task); +/* copy of the initial thread info (which contains init_task) */ +struct thread_info init_thread = INIT_THREAD_INFO(init_task); + +long do_no_restart_syscall(struct restart_block *param) +{ + return -EINTR; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/inodes.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/inodes.c.svn-base new file mode 100644 index 00000000..9ef02ed5 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/inodes.c.svn-base @@ -0,0 +1,311 @@ +/** lib/src/arch/l4/inodes.c + * + * Assorted dummies implementing inode and superblock access functions, + * which are used by the block layer stuff, but not needed in DDE_Linux. + */ + +#include "local.h" + +#include +#include +#include + +/* + * Linux' global list of all super blocks. + */ +LIST_HEAD(super_blocks); + +/********************************** + * Inode stuff * + **********************************/ + +struct inode* new_inode(struct super_block *sb) +{ + if (sb->s_op->alloc_inode) + return sb->s_op->alloc_inode(sb); + + return kzalloc(sizeof(struct inode), GFP_KERNEL); +} + +void __mark_inode_dirty(struct inode *inode, int flags) +{ + WARN_UNIMPL; +} + +void iput(struct inode *inode) +{ + WARN_UNIMPL; +} + +void generic_delete_inode(struct inode *inode) +{ + WARN_UNIMPL; +} + +int invalidate_inodes(struct super_block * sb) +{ + WARN_UNIMPL; + return 0; +} + +void truncate_inode_pages(struct address_space *mapping, loff_t lstart) +{ + WARN_UNIMPL; +} + +void touch_atime(struct vfsmount *mnt, struct dentry *dentry) +{ + WARN_UNIMPL; +} + +/********************************** + * Superblock stuff * + **********************************/ + +struct super_block * get_super(struct block_device *bdev) +{ + WARN_UNIMPL; + return NULL; +} + +int simple_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + WARN_UNIMPL; + return 0; +} + +void kill_anon_super(struct super_block *sb) +{ + WARN_UNIMPL; +} + +void shrink_dcache_sb(struct super_block * sb) +{ + WARN_UNIMPL; +} + +void drop_super(struct super_block *sb) +{ + WARN_UNIMPL; +} + +struct inode_operations empty_iops = { }; +struct file_operations empty_fops = { }; + +/**! Alloc and init a new inode. + * + * Basically stolen from linux/fs/inode.c:alloc_inode() + */ +static struct inode *dde_alloc_inode(struct super_block *sb) +{ + struct inode *inode; + + if (sb->s_op->alloc_inode) + inode = sb->s_op->alloc_inode(sb); + else + inode = kzalloc(sizeof(*inode), GFP_KERNEL); + + if (inode) { + inode->i_sb = sb; + inode->i_blkbits = sb->s_blocksize_bits; + inode->i_flags = 0; + atomic_set(&inode->i_count, 1); + inode->i_op = &empty_iops; + inode->i_fop = &empty_fops; + inode->i_nlink = 1; + atomic_set(&inode->i_writecount, 0); + inode->i_size = 0; + inode->i_blocks = 0; + inode->i_bytes = 0; + inode->i_generation = 0; + inode->i_pipe = NULL; + inode->i_bdev = NULL; + inode->i_cdev = NULL; + inode->i_rdev = 0; + inode->dirtied_when = 0; + inode->i_private = NULL; + } + + return inode; +} + + +void __iget(struct inode *inode) +{ + atomic_inc(&inode->i_count); +} + + +static struct inode *dde_new_inode(struct super_block *sb, struct list_head *head, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), void *data) +{ + struct inode *ret = dde_alloc_inode(sb); + int err = 0; + + if (set) + err = set(ret, data); + + BUG_ON(err); + + __iget(ret); + ret->i_state = I_LOCK|I_NEW; + + list_add_tail(&ret->i_sb_list, &sb->s_inodes); + + return ret; +} + + +struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), void *data) +{ + struct inode *inode = NULL; + struct list_head *p; + + list_for_each(p, &sb->s_inodes) { + struct inode *i = list_entry(p, struct inode, i_sb_list); + if (test) { + if (!test(i, data)) { + DEBUG_MSG("test false"); + continue; + } + else { + inode = i; + break; + } + } + } + + if (inode) + return inode; + + return dde_new_inode(sb, &sb->s_inodes, test, set, data); +} + +void unlock_new_inode(struct inode *inode) +{ + inode->i_state &= ~(I_LOCK | I_NEW); + wake_up_bit(&inode->i_state, __I_LOCK); +} + +struct super_block *sget(struct file_system_type *type, + int (*test)(struct super_block *, void*), + int (*set)(struct super_block *, void*), + void *data) +{ + struct super_block *s = NULL; + struct list_head *p; + int err; + + if (test) { + list_for_each(p, &type->fs_supers) { + struct super_block *block = list_entry(p, + struct super_block, + s_instances); + if (!test(block, data)) + continue; + return block; + } + } + + s = kzalloc(sizeof(*s), GFP_KERNEL); + BUG_ON(!s); + + INIT_LIST_HEAD(&s->s_dirty); + INIT_LIST_HEAD(&s->s_io); + INIT_LIST_HEAD(&s->s_files); + INIT_LIST_HEAD(&s->s_instances); + INIT_HLIST_HEAD(&s->s_anon); + INIT_LIST_HEAD(&s->s_inodes); + init_rwsem(&s->s_umount); + mutex_init(&s->s_lock); + lockdep_set_class(&s->s_umount, &type->s_umount_key); + /* + * The locking rules for s_lock are up to the + * filesystem. For example ext3fs has different + * lock ordering than usbfs: + */ + lockdep_set_class(&s->s_lock, &type->s_lock_key); + down_write(&s->s_umount); + s->s_count = S_BIAS; + atomic_set(&s->s_active, 1); + mutex_init(&s->s_vfs_rename_mutex); + mutex_init(&s->s_dquot.dqio_mutex); + mutex_init(&s->s_dquot.dqonoff_mutex); + init_rwsem(&s->s_dquot.dqptr_sem); + init_waitqueue_head(&s->s_wait_unfrozen); + s->s_maxbytes = MAX_NON_LFS; +#if 0 + s->dq_op = sb_dquot_ops; + s->s_qcop = sb_quotactl_ops; + s->s_op = &default_op; +#endif + s->s_time_gran = 1000000000; + + err = set(s, data); + BUG_ON(err); + + s->s_type = type; + strlcpy(s->s_id, type->name, sizeof(s->s_id)); + list_add_tail(&s->s_list, &super_blocks); + list_add(&s->s_instances, &type->fs_supers); + __module_get(type->owner); + return s; +} + +int set_anon_super(struct super_block *s, void *data) +{ + WARN_UNIMPL; + return 0; +} + +int get_sb_pseudo(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, unsigned long magic, + struct vfsmount *mnt) +{ + struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); + struct super_operations default_ops = {}; + struct inode *root = NULL; + struct dentry *dentry = NULL; + struct qstr d_name = {.name = name, .len = strlen(name)}; + + BUG_ON(IS_ERR(s)); + + s->s_flags = MS_NOUSER; + s->s_maxbytes = ~0ULL; + s->s_blocksize = 1024; + s->s_blocksize_bits = 10; + s->s_magic = magic; + s->s_op = ops ? ops : &default_ops; + s->s_time_gran = 1; + root = new_inode(s); + + BUG_ON(!root); + + root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; + root->i_uid = root->i_gid = 0; +#if 0 + root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; + dentry = d_alloc(NULL, &d_name); + dentry->d_sb = s; + dentry->d_parent = dentry; + d_instantiate(dentry, root); +#endif + s->s_root = dentry; + s->s_flags |= MS_ACTIVE; + + mnt->mnt_sb = s; + mnt->mnt_root = dget(s->s_root); + + DEBUG_MSG("root mnt sb @ %p", mnt->mnt_sb); + + return 0; +} + +void inode_init_once(struct inode *inode) +{ + WARN_UNIMPL; +} + diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/irq.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/irq.c.svn-base new file mode 100644 index 00000000..0e565e54 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/irq.c.svn-base @@ -0,0 +1,247 @@ +/* + * \brief Hardware-interrupt support + * \author Christian Helmuth + * \date 2007-02-12 + * + * + * + * XXX Consider support for IRQ_HANDLED and friends (linux/irqreturn.h) + */ + +/* Linux */ +#include +#include /* memset() */ + +/* DDEKit */ +#include +#include + +/* local */ +#include "dde26.h" +#include "local.h" + +/* dummy */ +irq_cpustat_t irq_stat[CONFIG_NR_CPUS]; + +/** + * IRQ handling data + */ +static struct dde_irq +{ + unsigned irq; /* IRQ number */ + unsigned count; /* usage count */ + int shared; /* shared IRQ */ + struct ddekit_thread *thread; /* DDEKit interrupt thread */ + struct irqaction *action; /* Linux IRQ action */ + + struct dde_irq *next; /* next DDE IRQ */ +} *used_irqs; + + +static void irq_thread_init(void *p) { + l4dde26_process_add_worker(); } + + +extern ddekit_sem_t *dde_softirq_sem; +static void irq_handler(void *arg) +{ + struct dde_irq *irq = arg; + struct irqaction *action; + +#if 0 + DEBUG_MSG("irq 0x%x", irq->irq); +#endif + /* interrupt occurred - call all handlers */ + for (action = irq->action; action; action = action->next) { + irqreturn_t r = action->handler(action->irq, action->dev_id); +#if 0 + DEBUG_MSG("return: %s", r == IRQ_HANDLED ? "IRQ_HANDLED" : r == IRQ_NONE ? "IRQ_NONE" : "??"); +#endif + } + + /* upon return we check for pending soft irqs */ + if (local_softirq_pending()) + ddekit_sem_up(dde_softirq_sem); +} + + +/***************************** + ** IRQ handler bookkeeping ** + *****************************/ + +/** + * Claim IRQ + * + * \return usage counter or negative error code + * + * FIXME list locking + * FIXME are there more races? + */ +static int claim_irq(struct irqaction *action) +{ + int shared = action->flags & IRQF_SHARED ? 1 : 0; + struct dde_irq *irq; + + /* check if IRQ already used */ + for (irq = used_irqs; irq; irq = irq->next) + if (irq->irq == action->irq) break; + + /* we have to setup IRQ handling */ + if (!irq) { + /* allocate and initalize new descriptor */ + irq = ddekit_simple_malloc(sizeof(*irq)); + if (!irq) return -ENOMEM; + memset(irq, 0, sizeof(*irq)); + + irq->irq = action->irq; + irq->shared = shared; + irq->next = used_irqs; + used_irqs = irq; + + /* attach to interrupt */ + irq->thread = ddekit_interrupt_attach(irq->irq, + irq->shared, + irq_thread_init, + irq_handler, + (void *)irq); + if (!irq->thread) { + ddekit_simple_free(irq); + return -EBUSY; + } + } + + /* does desciptor allow our new handler? */ + if ((!irq->shared || !shared) && irq->action) return -EBUSY; + + /* add handler */ + irq->count++; + action->next = irq->action; + irq->action = action; + + return irq->count; +} + + +/** + * Free previously claimed IRQ + * + * \return usage counter or negative error code + */ +static struct irqaction *release_irq(unsigned irq_num, void *dev_id) +{ + struct dde_irq *prev_irq, *irq; + + /* check if IRQ already used */ + for (prev_irq = 0, irq = used_irqs; irq; + prev_irq = irq, irq = irq->next) + if (irq->irq == irq_num) break; + + if (!irq) return 0; + + struct irqaction *prev_action, *action; + + for (prev_action = 0, action = irq->action; action; + prev_action = action, action = action->next) + if (action->dev_id == dev_id) break; + + if (!action) return 0; + + /* dequeue action from irq */ + if (prev_action) + prev_action->next = action->next; + else + irq->action = action->next; + + /* dequeue irq from used_irqs list and free structure, + if no more actions available */ + if (!irq->action) { + if (prev_irq) + prev_irq->next = irq->next; + else + used_irqs = irq->next; + + /* detach from interrupt */ + ddekit_interrupt_detach(irq->irq); + + ddekit_simple_free(irq); + } + + return action; +} + + +/*************** + ** Linux API ** + ***************/ + +/** + * Request interrupt + * + * \param irq interrupt number + * \param handler interrupt handler -> top half + * \param flags interrupt handling flags (SA_SHIRQ, ...) + * \param dev_name device name + * \param dev_id cookie passed back to handler + * + * \return 0 on success; error code otherwise + * + * \todo FIXME consider locking! + */ +int request_irq(unsigned int irq, irq_handler_t handler, + unsigned long flags, const char *dev_name, void *dev_id) +{ + if (!handler) return -EINVAL; + + /* facilitate Linux irqaction for this handler */ + struct irqaction *irq_action = ddekit_simple_malloc(sizeof(*irq_action)); + if (!irq_action) return -ENOMEM; + memset(irq_action, 0, sizeof(*irq_action)); + + irq_action->handler = handler; + irq_action->flags = flags; + irq_action->name = dev_name; + irq_action->dev_id = dev_id; + irq_action->irq = irq; + + /* attach to IRQ */ + int err = claim_irq(irq_action); + if (err < 0) return err; + + return 0; +} + +/** Release Interrupt + * \ingroup mod_irq + * + * \param irq interrupt number + * \param dev_id cookie passed back to handler + * + */ +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *irq_action = release_irq(irq, dev_id); + + if (irq_action) + ddekit_simple_free(irq_action); +} + +void disable_irq(unsigned int irq) +{ + ddekit_interrupt_disable(irq); +} + +void disable_irq_nosync(unsigned int irq) +{ + /* + * Note: + * In contrast to the _nosync semantics, DDEKit's + * disable definitely waits until a currently executed + * IRQ handler terminates. + */ + ddekit_interrupt_disable(irq); +} + +void enable_irq(unsigned int irq) +{ + ddekit_interrupt_enable(irq); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmalloc.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmalloc.c.svn-base new file mode 100644 index 00000000..065c13c7 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmalloc.c.svn-base @@ -0,0 +1,199 @@ +/* + * \brief kmalloc() implementation + * \author Christian Helmuth + * \date 2007-01-24 + * + * In Linux 2.6 this resides in mm/slab.c. + * + * This implementation of kmalloc() stays with Linux's and uses kmem_caches for + * some power of two bytes. For larger allocations ddedkit_large_malloc() is + * used. This way, we optimize for speed and potentially waste memory + * resources. + */ + +/* Linux */ +#include +#include +#include +#include +#include +#include +#include + +/* DDEKit */ +#include +#include + +#include + +/* dummy */ +int forbid_dac; + +/* This stuff is needed by some drivers, e.g. for ethtool. + * XXX: This is a fake, implement it if you really need ethtool stuff. + */ +struct page* mem_map = NULL; +static bootmem_data_t contig_bootmem_data; +struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data }; + +int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + return 0; +} +EXPORT_SYMBOL(remap_pfn_range); + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_MALLOC 0 + +/******************** + ** Implementation ** + ********************/ + +/* + * These are the default caches for kmalloc. Custom caches can have other sizes. + */ +static struct cache_sizes malloc_sizes[] = { +#define CACHE(x) { .cs_size = (x) }, +#include + CACHE(ULONG_MAX) +#undef CACHE +}; + + +/* + * kmalloc() cache names + */ +static const char *malloc_names[] = { +#define CACHE(x) "size-" #x, +#include + NULL +#undef CACHE +}; + + +/** + * Find kmalloc() cache for size + */ +static struct kmem_cache *find_cache(size_t size) +{ + struct cache_sizes *sizes; + + for (sizes = malloc_sizes; size > sizes->cs_size; ++sizes) ; + + return sizes->cs_cachep; +} + + +/** + * Free previously allocated memory + * @objp: pointer returned by kmalloc. + * + * If @objp is NULL, no operation is performed. + * + * Don't free memory not originally allocated by kmalloc() + * or you will run into trouble. + */ +void kfree(const void *objp) +{ + if (!objp) return; + + /* find cache back-pointer */ + void **p = (void **)objp - 1; + + ddekit_log(DEBUG_MALLOC, "objp=%p cache=%p (%d)", + p, *p, *p ? kmem_cache_size(*p) : 0); + + if (*p) + /* free from cache */ + kmem_cache_free(*p, p); + else + /* no cache for this size - use ddekit free */ + ddekit_large_free(p); +} + + +/** + * Allocate memory + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * + * kmalloc is the normal method of allocating memory + * in the kernel. + */ +void *__kmalloc(size_t size, gfp_t flags) +{ + /* add space for back-pointer */ + size += sizeof(void *); + + /* find appropriate cache */ + struct kmem_cache *cache = find_cache(size); + + void **p; + if (cache) + /* allocate from cache */ + p = kmem_cache_alloc(cache, flags); + else + /* no cache for this size - use ddekit malloc */ + p = ddekit_large_malloc(size); + + ddekit_log(DEBUG_MALLOC, "size=%d, cache=%p (%d) => %p", + size, cache, cache ? kmem_cache_size(cache) : 0, p); + + /* return pointer to actual chunk */ + if (p) { + *p = cache; + p++; + } + return p; +} + + +size_t ksize(const void *p) +{ + struct kmem_cache *cache = (struct kmem_cache *)*((void**)p - 1); + if (cache) + return kmem_cache_size(cache); + return -1; +} + + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret = (void *)__get_free_pages(flag, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + + +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + + +/******************** + ** Initialization ** + ********************/ + +/** + * dde_linux kmalloc initialization + */ +void l4dde26_kmalloc_init(void) +{ + struct cache_sizes *sizes = malloc_sizes; + const char **names = malloc_names; + + /* init malloc sizes array */ + for (; sizes->cs_size != ULONG_MAX; ++sizes, ++names) + sizes->cs_cachep = kmem_cache_create(*names, sizes->cs_size, 0, 0, 0); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmem_cache.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmem_cache.c.svn-base new file mode 100644 index 00000000..1465ac6c --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/kmem_cache.c.svn-base @@ -0,0 +1,213 @@ +/* + * \brief Kmem_cache implementation + * \author Christian Helmuth + * \date 2007-01-22 + * + * In Linux 2.6 this resides in mm/slab.c. + * + * I'll disregard the following function currently... + * + * extern struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags); + * extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); + */ + +/* Linux */ +#include + +/* DDEKit */ +#include +#include + + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_SLAB 0 + +#if DEBUG_SLAB +# define DEBUG_SLAB_ALLOC 1 +#else +# define DEBUG_SLAB_ALLOC 0 +#endif + +/* + * Kmem cache structure + */ +struct kmem_cache +{ + const char *name; /**< cache name */ + unsigned size; /**< obj size */ + + struct ddekit_slab *ddekit_slab_cache; /**< backing DDEKit cache */ + ddekit_lock_t cache_lock; /**< lock */ + void (*ctor)(void *); /**< object constructor */ +}; + + +/** + * Return size of objects in cache + */ +unsigned int kmem_cache_size(struct kmem_cache *cache) +{ + return cache->size; +} + + +/** + * Return name of cache + */ +const char *kmem_cache_name(struct kmem_cache *cache) +{ + return cache->name; +} + + +/** + * kmem_cache_shrink - Shrink a cache. + * @cachep: The cache to shrink. + * + * Releases as many slabs as possible for a cache. + * To help debugging, a zero exit status indicates all slabs were released. + */ +int kmem_cache_shrink(struct kmem_cache *cache) +{ + /* noop */ + return 1; +} + + +/** + * kmem_cache_free - Deallocate an object + * @cachep: The cache the allocation was from. + * @objp: The previously allocated object. + * + * Free an object which was previously allocated from this + * cache. + */ +void kmem_cache_free(struct kmem_cache *cache, void *objp) +{ + ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" (%p)", cache->name, objp); + + ddekit_lock_lock(&cache->cache_lock); + ddekit_slab_free(cache->ddekit_slab_cache, objp); + ddekit_lock_unlock(&cache->cache_lock); +} + + +/** + * kmem_cache_alloc - Allocate an object + * @cachep: The cache to allocate from. + * @flags: See kmalloc(). + * + * Allocate an object from this cache. The flags are only relevant + * if the cache has no available objects. + */ +void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) +{ + void *ret; + + ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" flags=%x", cache->name, flags); + + ddekit_lock_lock(&cache->cache_lock); + ret = ddekit_slab_alloc(cache->ddekit_slab_cache); + ddekit_lock_unlock(&cache->cache_lock); + + // XXX: is it valid to run ctor AND memset to zero? + if (flags & __GFP_ZERO) + memset(ret, 0, cache->size); + else if (cache->ctor) + cache->ctor(ret); + + return ret; +} + + +/** + * kmem_cache_destroy - delete a cache + * @cachep: the cache to destroy + * + * Remove a struct kmem_cache object from the slab cache. + * Returns 0 on success. + * + * It is expected this function will be called by a module when it is + * unloaded. This will remove the cache completely, and avoid a duplicate + * cache being allocated each time a module is loaded and unloaded, if the + * module doesn't have persistent in-kernel storage across loads and unloads. + * + * The cache must be empty before calling this function. + * + * The caller must guarantee that noone will allocate memory from the cache + * during the kmem_cache_destroy(). + */ +void kmem_cache_destroy(struct kmem_cache *cache) +{ + ddekit_log(DEBUG_SLAB, "\"%s\"", cache->name); + + ddekit_slab_destroy(cache->ddekit_slab_cache); + ddekit_simple_free(cache); +} + + +/** + * kmem_cache_create - Create a cache. + * @name: A string which is used in /proc/slabinfo to identify this cache. + * @size: The size of objects to be created in this cache. + * @align: The required alignment for the objects. + * @flags: SLAB flags + * @ctor: A constructor for the objects. + * + * Returns a ptr to the cache on success, NULL on failure. + * Cannot be called within a int, but can be interrupted. + * The @ctor is run when new pages are allocated by the cache + * and the @dtor is run before the pages are handed back. + * + * @name must be valid until the cache is destroyed. This implies that + * the module calling this has to destroy the cache before getting unloaded. + * + * The flags are + * + * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) + * to catch references to uninitialised memory. + * + * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check + * for buffer overruns. + * + * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware + * cacheline. This can be beneficial if you're counting cycles as closely + * as davem. + */ +struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, + unsigned long flags, + void (*ctor)(void *)) +{ + ddekit_log(DEBUG_SLAB, "\"%s\" obj_size=%d", name, size); + + struct kmem_cache *cache; + + if (!name) { + printk("kmem_cache name reqeuired\n"); + return 0; + } + + cache = ddekit_simple_malloc(sizeof(*cache)); + if (!cache) { + printk("No memory for slab cache\n"); + return 0; + } + + /* Initialize a physically contiguous cache for kmem */ + if (!(cache->ddekit_slab_cache = ddekit_slab_init(size, 1))) { + printk("DDEKit slab init failed\n"); + ddekit_simple_free(cache); + return 0; + } + + cache->name = name; + cache->size = size; + cache->ctor = ctor; + + ddekit_lock_init_unlocked(&cache->cache_lock); + + return cache; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/local.h.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/local.h.svn-base new file mode 100644 index 00000000..35b3e449 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/local.h.svn-base @@ -0,0 +1,99 @@ +#ifndef __DDE26_LOCAL_H +#define __DDE26_LOCAL_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DDE_DEBUG 1 +#define DDE_FERRET 0 + +/* Ferret Debugging stuff, note that this is the only point we are using + * L4 headers directly and only for debugging. */ +#if DDE_FERRET +#include +#include +#include +#include +#include +#include +extern ferret_list_local_t *ferret_ore_sensor; +#endif + +/*** + * Internal representation of a Linux kernel thread. This struct + * contains Linux' data as well as some additional data used by DDE. + */ +typedef struct dde26_thread_data +{ + /* NOTE: _threadinfo needs to be first in this struct! */ + struct thread_info _thread_info; ///< Linux thread info (see current()) + ddekit_thread_t *_ddekit_thread; ///< underlying DDEKit thread + ddekit_sem_t *_sleep_lock; ///< lock used for sleep_interruptible() + struct pid _vpid; ///< virtual PID +} dde26_thread_data; + +#define LX_THREAD(thread_data) ((thread_data)->_thread_info) +#define LX_TASK(thread_data) ((thread_data)->_thread_info.task) +#define DDEKIT_THREAD(thread_data) ((thread_data)->_ddekit_thread) +#define SLEEP_LOCK(thread_data) ((thread_data)->_sleep_lock) +#define VPID_P(thread_data) (&(thread_data)->_vpid) + +#if DDE_DEBUG +#define WARN_UNIMPL printk("unimplemented: %s\n", __FUNCTION__) +#define DEBUG_MSG(msg, ...) printk("%s: \033[36m"msg"\033[0m\n", __FUNCTION__, ##__VA_ARGS__) + +#define DECLARE_INITVAR(name) \ + static struct { \ + int _initialized; \ + char *name; \ + } init_##name = {0, #name,} + +#define INITIALIZE_INITVAR(name) init_##name._initialized = 1 + +#define CHECK_INITVAR(name) \ + if (init_##name._initialized == 0) { \ + printk("DDE26: \033[31;1mUsing uninitialized subsystem: "#name"\033[0m\n"); \ + BUG(); \ + } + +#else /* !DDE_DEBUG */ + +#define WARN_UNIMPL do {} while(0) +#define DEBUG_MSG(...) do {} while(0) +#define DECLARE_INITVAR(name) +#define CHECK_INITVAR(name) do {} while(0) +#define INITIALIZE_INITVAR(name) do {} while(0) + +#endif + +/* since _thread_info always comes first in the thread_data struct, + * we can derive the dde26_thread_data from a task struct by simply + * dereferencing its thread_info pointer + */ +static dde26_thread_data *lxtask_to_ddethread(struct task_struct *t) +{ + return (dde26_thread_data *)(task_thread_info(t)); +} + +extern struct thread_info init_thread; +extern struct task_struct init_task; + +#endif diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/mm-helper.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/mm-helper.c.svn-base new file mode 100644 index 00000000..68c0213b --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/mm-helper.c.svn-base @@ -0,0 +1,45 @@ +/* Linux */ +#include +#include +#include + +/* DDEKit */ +#include +#include +#include + +#include "local.h" + +int ioprio_best(unsigned short aprio, unsigned short bprio) +{ + WARN_UNIMPL; + return 0; +} + +void *__alloc_bootmem(unsigned long size, unsigned long align, + unsigned long goal) +{ + WARN_UNIMPL; + return 0; +} + +/* + * Stolen from linux-2.6.29/fs/libfs.c + */ +ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, + const void *from, size_t available) +{ + loff_t pos = *ppos; + if (pos < 0) + return -EINVAL; + if (pos > available) + return 0; + if (count > available - pos) + count = available - pos; + memcpy(to, from + pos, count); + *ppos = pos + count; + + return count; +} + +int capable(int f) { return 1; } diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/net.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/net.c.svn-base new file mode 100644 index 00000000..d6637d96 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/net.c.svn-base @@ -0,0 +1,36 @@ +/****************************************************************************** + * DDELinux networking utilities. * + * * + * Bjoern Doebel * + * * + * (c) 2005 - 2007 Technische Universitaet Dresden * + * This file is part of DROPS, which is distributed under the terms of the * + * GNU General Public License 2. Please see the COPYING file for details. * + ******************************************************************************/ + +#include + +#include +#include + +#include "local.h" + + +/* Callback function to be called if a network packet arrives and needs to + * be handled by netif_rx() or netif_receive_skb() + */ +linux_rx_callback l4dde26_rx_callback = NULL; + + +/* Register a netif_rx callback function. + * + * \return pointer to old callback function + */ +linux_rx_callback l4dde26_register_rx_callback(linux_rx_callback cb) +{ + linux_rx_callback old = l4dde26_rx_callback; + l4dde26_rx_callback = cb; + DEBUG_MSG("New rx callback @ %p.", cb); + + return old; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/page_alloc.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/page_alloc.c.svn-base new file mode 100644 index 00000000..0a2e3fdf --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/page_alloc.c.svn-base @@ -0,0 +1,281 @@ +/* + * \brief Page allocation + * \author Christian Helmuth + * Bjoern Doebel + * \date 2007-01-22 + * + * In Linux 2.6 this resides in mm/page_alloc.c. + * + * This implementation is far from complete as it does not cover "struct page" + * emulation. In Linux, there's an array of structures for all pages. In + * particular, iteration works for this array like: + * + * struct page *p = alloc_pages(3); // p refers to first page of allocation + * ++p; // p refers to second page + * + * There may be more things to cover and we should have a deep look into the + * kernel parts we want to reuse. Candidates for problems may be file systems, + * storage (USB, IDE), and video (bttv). + */ + +/* Linux */ +#include +#include +#include +#include +#include + +/* DDEKit */ +#include +#include +#include + +#include "local.h" + +unsigned long max_low_pfn; +unsigned long min_low_pfn; +unsigned long max_pfn; + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_PAGE_ALLOC 0 + + +/* + * DDE page cache + * + * We need to store all pages somewhere (which in the Linux kernel is + * performed by the huge VM infrastructure. Purpose for us is: + * - make virt_to_phys() work + * - enable external clients to hand in memory (e.g., a dm_phys + * dataspace and make it accessible as Linux pages to the DDE) + */ + +#define DDE_PAGE_CACHE_SHIFT 10 +#define DDE_PAGE_CACHE_SIZE (1 << DDE_PAGE_CACHE_SHIFT) +#define DDE_PAGE_CACHE_MASK (DDE_PAGE_CACHE_SIZE - 1) + +typedef struct +{ + struct hlist_node list; + struct page *page; +} page_cache_entry; + +static struct hlist_head dde_page_cache[DDE_PAGE_CACHE_SIZE]; + +/** Hash function to map virtual addresses to page cache buckets. */ +#define VIRT_TO_PAGEHASH(a) ((((unsigned long)a) >> PAGE_SHIFT) & DDE_PAGE_CACHE_MASK) + + +void dde_page_cache_add(struct page *p) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(p->virtual); + + page_cache_entry *e = kmalloc(sizeof(page_cache_entry), GFP_KERNEL); + +#if DEBUG_PAGE_ALLOC + DEBUG_MSG("virt %p, hash: %x", p->virtual, hashval); +#endif + + e->page = p; + INIT_HLIST_NODE(&e->list); + + hlist_add_head(&e->list, &dde_page_cache[hashval]); +} + + +void dde_page_cache_remove(struct page *p) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(p->virtual); + struct hlist_node *hn = NULL; + struct hlist_head *h = &dde_page_cache[hashval]; + page_cache_entry *e = NULL; + struct hlist_node *v = NULL; + + hlist_for_each_entry(e, hn, h, list) { + if ((unsigned long)e->page->virtual == ((unsigned long)p->virtual & PAGE_MASK)) + v = hn; + break; + } + + if (v) { +#if DEBUG_PAGE_ALLOC + DEBUG_MSG("deleting node %p which contained page %p", v, p); +#endif + hlist_del(v); + } +} + + +struct page* dde_page_lookup(unsigned long va) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(va); + + struct hlist_node *hn = NULL; + struct hlist_head *h = &dde_page_cache[hashval]; + page_cache_entry *e = NULL; + + hlist_for_each_entry(e, hn, h, list) { + if ((unsigned long)e->page->virtual == (va & PAGE_MASK)) + return e->page; + } + + return NULL; +} + + +struct page * __alloc_pages_internal(gfp_t gfp_mask, unsigned int order, + struct zonelist *zonelist, nodemask_t *nm) +{ + /* XXX: In fact, according to order, we should have one struct page + * for every page, not only for the first one. + */ + struct page *ret = kmalloc(sizeof(*ret), GFP_KERNEL); + + ret->virtual = (void *)__get_free_pages(gfp_mask, order); + dde_page_cache_add(ret); + + return ret; +} + + +unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) +{ + ddekit_log(DEBUG_PAGE_ALLOC, "gfp_mask=%x order=%d (%d bytes)", + gfp_mask, order, PAGE_SIZE << order); + + Assert(gfp_mask != GFP_DMA); + void *p = ddekit_large_malloc(PAGE_SIZE << order); + + return (unsigned long)p; +} + + +unsigned long get_zeroed_page(gfp_t gfp_mask) +{ + unsigned long p = __get_free_pages(gfp_mask, 0); + + if (p) memset((void *)p, 0, PAGE_SIZE); + + return (unsigned long)p; +} + + +void free_hot_page(struct page *page) +{ + WARN_UNIMPL; +} + +/* + * XXX: If alloc_pages() gets fixed to allocate a page struct per page, + * this needs to be adapted, too. + */ +void __free_pages(struct page *page, unsigned int order) +{ + free_pages((unsigned long)page->virtual, order); + dde_page_cache_remove(page); +} + +void __pagevec_free(struct pagevec *pvec) +{ + WARN_UNIMPL; +} + +int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, int len, int write, int force, + struct page **pages, struct vm_area_struct **vmas) +{ + WARN_UNIMPL; + return 0; +} + +/** + * ... + * + * XXX order may be larger than allocation at 'addr' - it may comprise several + * allocation via __get_free_pages()! + */ +void free_pages(unsigned long addr, unsigned int order) +{ + ddekit_log(DEBUG_PAGE_ALLOC, "addr=%p order=%d", (void *)addr, order); + + ddekit_large_free((void *)addr); +} + + +unsigned long __pa(volatile void *addr) +{ + return ddekit_pgtab_get_physaddr((void*)addr); +} + +void *__va(unsigned long addr) +{ + return (void*)ddekit_pgtab_get_virtaddr((ddekit_addr_t) addr); +} + + +int set_page_dirty_lock(struct page *page) +{ + WARN_UNIMPL; + return 0; +} + + +/* + * basically copied from linux/mm/page_alloc.c + */ +void *__init alloc_large_system_hash(const char *tablename, + unsigned long bucketsize, + unsigned long numentries, + int scale, + int flags, + unsigned int *_hash_shift, + unsigned int *_hash_mask, + unsigned long limit) +{ + void * table = NULL; + unsigned long log2qty; + unsigned long size; + + if (numentries == 0) + numentries = 1024; + + log2qty = ilog2(numentries); + size = bucketsize << log2qty; + + do { + unsigned long order; + for (order = 0; ((1UL << order) << PAGE_SHIFT) < size; order++); + table = (void*) __get_free_pages(GFP_ATOMIC, order); + } while (!table && size > PAGE_SIZE && --log2qty); + + if (!table) + panic("Failed to allocate %s hash table\n", tablename); + + printk("%s hash table entries: %d (order: %d, %lu bytes)\n", + tablename, + (1U << log2qty), + ilog2(size) - PAGE_SHIFT, + size); + + if (_hash_shift) + *_hash_shift = log2qty; + if (_hash_mask) + *_hash_mask = (1 << log2qty) - 1; + + return table; +} + + +static void __init dde_page_cache_init(void) +{ + printk("Initializing DDE page cache\n"); + int i=0; + + for (i; i < DDE_PAGE_CACHE_SIZE; ++i) + INIT_HLIST_HEAD(&dde_page_cache[i]); +} + +core_initcall(dde_page_cache_init); diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/param.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/param.c.svn-base new file mode 100644 index 00000000..5bd83f32 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/param.c.svn-base @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Lazy bastard, eh? */ +#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ + int param_set_##name(const char *val, struct kernel_param *kp) \ + { \ + return 0; \ + } \ + int param_get_##name(char *buffer, struct kernel_param *kp) \ + { \ + return 0;\ + } + +STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol); +STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol); +STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); +STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); + +int printk_ratelimit(void) +{ + return 0; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/pci.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/pci.c.svn-base new file mode 100644 index 00000000..2a0391f2 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/pci.c.svn-base @@ -0,0 +1,189 @@ +#include "local.h" + +#include +#include +#include +#include + +/* will include $(CONTRIB)/drivers/pci/pci.h */ +#include "pci.h" + +DECLARE_INITVAR(dde26_pci); + +/** PCI device descriptor */ +typedef struct l4dde_pci_dev { + struct list_head next; /**< chain info */ + struct ddekit_pci_dev *ddekit_dev; /**< corresponding DDEKit descriptor */ + struct pci_dev *linux_dev; /**< Linux descriptor */ +} l4dde_pci_dev_t; + + +/******************************************************************************************* + ** PCI data ** + *******************************************************************************************/ +/** List of Linux-DDEKit PCIDev mappings */ +static LIST_HEAD(pcidev_mappings); + +/** PCI bus */ +static struct pci_bus *pci_bus = NULL; + +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); + +/** PCI operations for our virtual PCI bus */ +static struct pci_ops dde_pcibus_ops = { + .read = l4dde26_pci_read, + .write = l4dde26_pci_write, +}; + + +/******************************************************************************************* + ** Read/write PCI config space. This is simply mapped to the DDEKit functions. ** + *******************************************************************************************/ +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) +{ + return ddekit_pci_read(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + return ddekit_pci_write(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +int pci_irq_enable(struct pci_dev *dev) +{ + int irq = dev->irq; + int pin = 0; + int ret; + + DEBUG_MSG("dev %p", dev); + if (!dev) + return -EINVAL; + + pin = (int)dev->pin; + DEBUG_MSG("irq %d, pin %d", dev->irq, dev->pin); + if (!pin) { + dev_warn(&dev->dev, + "No interrupt pin configured for device %s\n", + pci_name(dev)); + return 0; + } + pin--; + + ret = ddekit_pci_irq_enable(dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), pin, &irq); + if (ret) { + dev_warn(&dev->dev, "Interrupt enable failed for device %s (%d)\n", + pci_name(dev), ret); + return -1; + } + + dev_info(&dev->dev, "PCI INT %c -> GSI %d -> IRQ %d\n", + 'A' + pin, irq, dev->irq); + + dev->irq = irq; + return 0; +} + +int __pci_enable_device(struct pci_dev *dev) +{ + WARN_UNIMPL; + return 0; +} + + +/** + * pci_enable_device - Initialize device before it's used by a driver. + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O and memory. Wake up the device if it was suspended. + * Beware, this function can fail. + * + * \param dev PCI device to be initialized + * + */ +int +pci_enable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); +// WARN_UNIMPL; + return pci_irq_enable(dev); +} + + +/** + * pci_disable_device - Disable PCI device after use + * + * Signal to the system that the PCI device is not in use by the system + * anymore. This only involves disabling PCI bus-mastering, if active. + * + * \param dev PCI device to be disabled + */ +void pci_disable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); + WARN_UNIMPL; +} + + +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) +{ + //WARN_UNIMPL; +} + +void pci_set_master(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); + WARN_UNIMPL; +} + + +int pci_create_sysfs_dev_files(struct pci_dev *pdev) +{ + return 0; +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +void +pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + WARN_UNIMPL; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ +#if 0 + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return pcibios_enable_irq(dev); +#endif + return 0; +} + +/******************************************************************************************* + ** Initialization function ** + *******************************************************************************************/ + +/** Initialize DDELinux PCI subsystem. + */ +void __init l4dde26_init_pci(void) +{ + ddekit_pci_init(); + + pci_bus = pci_create_bus(NULL, 0, &dde_pcibus_ops, NULL); + Assert(pci_bus); + + pci_do_scan_bus(pci_bus); + + INITIALIZE_INITVAR(dde26_pci); +} + +arch_initcall(l4dde26_init_pci); diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/power.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/power.c.svn-base new file mode 100644 index 00000000..e36487bd --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/power.c.svn-base @@ -0,0 +1,23 @@ +/* Dummy functions for power management. */ + +#include "local.h" +#include + +int device_pm_add(struct device * dev) +{ + WARN_UNIMPL; + return 0; +} + + +void device_pm_remove(struct device * dev) +{ + WARN_UNIMPL; +} + +int pm_qos_add_requirement(int qos, char *name, s32 value) { return 0; } +int pm_qos_update_requirement(int qos, char *name, s32 new_value) { return 0; } +void pm_qos_remove_requirement(int qos, char *name) { } +int pm_qos_requirement(int qos) { return 0; } +int pm_qos_add_notifier(int qos, struct notifier_block *notifier) { return 0; } +int pm_qos_remove_notifier(int qos, struct notifier_block *notifier) { return 0; } diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/process.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/process.c.svn-base new file mode 100644 index 00000000..5fe43b32 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/process.c.svn-base @@ -0,0 +1,347 @@ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "local.h" + +/***************************************************************************** + ** Current() implementation ** + *****************************************************************************/ +struct thread_info *current_thread_info(void) +{ + dde26_thread_data *cur = (dde26_thread_data *)ddekit_thread_get_my_data(); + return &LX_THREAD(cur); +} + +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +/***************************************************************************** + ** PID-related stuff ** + ** ** + ** Linux manages lists of PIDs that are handed out to processes so that at ** + ** a later point it is able to determine which task_struct belongs to a ** + ** certain PID. We implement this with a single list holding the mappings ** + ** for all our threads. ** + *****************************************************************************/ + +LIST_HEAD(_pid_task_list); +ddekit_lock_t _pid_task_list_lock; + +/** PID to task_struct mapping */ +struct pid2task +{ + struct list_head list; /**< list data */ + struct pid *pid; /**< PID */ + struct task_struct *ts; /**< task struct */ +}; + +struct pid init_struct_pid = INIT_STRUCT_PID; + +void put_pid(struct pid *pid) +{ + if (pid) + atomic_dec(&pid->count); + // no freeing here, our struct pid's are always allocated as + // part of the dde26_thread_data +} + +/** Attach PID to a certain task struct. */ +void attach_pid(struct task_struct *task, enum pid_type type + __attribute__((unused)), struct pid *pid) +{ + /* Initialize a new pid2task mapping */ + struct pid2task *pt = kmalloc(sizeof(struct pid2task), GFP_KERNEL); + pt->pid = get_pid(pid); + pt->ts = task; + + /* add to list */ + ddekit_lock_lock(&_pid_task_list_lock); + list_add(&pt->list, &_pid_task_list); + ddekit_lock_unlock(&_pid_task_list_lock); +} + +/** Detach PID from a task struct. */ +void detach_pid(struct task_struct *task, enum pid_type type __attribute__((unused))) +{ + struct list_head *p, *n, *h; + + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + /* search for mapping with given task struct and free it if necessary */ + list_for_each_safe(p, n, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pt->ts == task) { + put_pid(pt->pid); + list_del(p); + kfree(pt); + break; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); +} + +struct task_struct *find_task_by_pid_type(int type, int nr) +{ + struct list_head *h, *p; + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + list_for_each(p, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pid_nr(pt->pid) == nr) { + ddekit_lock_unlock(&_pid_task_list_lock); + return pt->ts; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); + + return NULL; +} + + +struct task_struct *find_task_by_pid_ns(int nr, struct pid_namespace *ns) +{ + /* we don't implement PID name spaces */ + return find_task_by_pid_type(0, nr); +} + +struct task_struct *find_task_by_pid(int nr) +{ + return find_task_by_pid_type(0, nr); +} + +/***************************************************************************** + ** kernel_thread() implementation ** + *****************************************************************************/ +/* Struct containing thread data for a newly created kthread. */ +struct __kthread_data +{ + int (*fn)(void *); + void *arg; + ddekit_lock_t lock; + dde26_thread_data *kthread; +}; + +/** Counter for running kthreads. It is used to create unique names + * for kthreads. + */ +static atomic_t kthread_count = ATOMIC_INIT(0); + +/** Entry point for new kernel threads. Make this thread a DDE26 + * worker and then execute the real thread fn. + */ +static void __kthread_helper(void *arg) +{ + struct __kthread_data *k = (struct __kthread_data *)arg; + + /* + * Make a copy of the fn and arg pointers, as the kthread struct is + * deleted by our parent after notifying it and this may happen before we + * get to execute the function. + */ + int (*_fn)(void*) = k->fn; + void *_arg = k->arg; + + l4dde26_process_add_worker(); + + /* + * Handshake with creator - we store our thread data in the + * kthread struct and then unlock the lock to notify our + * creator about completing setup + */ + k->kthread = (dde26_thread_data *)ddekit_thread_get_my_data(); + ddekit_lock_unlock(&k->lock); + + do_exit(_fn(_arg)); +} + +/** Our implementation of Linux' kernel_thread() function. Setup a new + * thread running our __kthread_helper() function. + */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + ddekit_thread_t *t; + char name[20]; + struct __kthread_data *kt = vmalloc(sizeof(struct __kthread_data)); + ddekit_lock_t lock; + + /* Initialize (and grab) handshake lock */ + ddekit_lock_init(&lock); + ddekit_lock_lock(&lock); + + int threadnum = atomic_inc_return(&kthread_count); + kt->fn = fn; + kt->arg = arg; + kt->lock = lock; // Copy lock ptr, note that kt is freed by the + // new thread, so we MUST NOT use kt->lock after + // this point! + + snprintf(name, 20, ".kthread%x", threadnum); + t = ddekit_thread_create(__kthread_helper, + (void *)kt, name); + Assert(t); + + ddekit_lock_lock(&lock); + ddekit_lock_deinit(&lock); + + return pid_nr(VPID_P(kt->kthread)); +} + +/** Our implementation of exit(). For DDE purposes this only relates + * to kernel threads. + */ +void do_exit(long code) +{ + ddekit_thread_t *t = DDEKIT_THREAD(lxtask_to_ddethread(current)); +// printk("Thread %s exits with code %x\n", ddekit_thread_get_name(t), code); + + /* do some cleanup */ + detach_pid(current, 0); + + /* goodbye, cruel world... */ + ddekit_thread_exit(); +} + +/***************************************************************************** + ** Misc functions ** + *****************************************************************************/ + +void dump_stack(void) +{ +} + + +char *get_task_comm(char *buf, struct task_struct *tsk) +{ + char *ret; + /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); + ret = strncpy(buf, tsk->comm, sizeof(tsk->comm)); + task_unlock(tsk); + return ret; +} + + +void set_task_comm(struct task_struct *tsk, char *buf) +{ + task_lock(tsk); + strlcpy(tsk->comm, buf, sizeof(tsk->comm)); + task_unlock(tsk); +} + + +/***************************************************************************** + ** DDEKit gluecode, init functions ** + *****************************************************************************/ +/* Initialize a dde26 thread. + * + * - Allocate thread data, as well as a Linux task struct, + * - Fill in default values for thread_info, and task, + * - Adapt task struct's thread_info backreference + * - Initialize the DDE sleep lock + */ +static dde26_thread_data *init_dde26_thread(void) +{ + /* + * Virtual PID counter + */ + static atomic_t pid_counter = ATOMIC_INIT(0); + dde26_thread_data *t = vmalloc(sizeof(dde26_thread_data)); + Assert(t); + + memcpy(&t->_vpid, &init_struct_pid, sizeof(struct pid)); + t->_vpid.numbers[0].nr = atomic_inc_return(&pid_counter); + + memcpy(&LX_THREAD(t), &init_thread, sizeof(struct thread_info)); + + LX_TASK(t) = vmalloc(sizeof(struct task_struct)); + Assert(LX_TASK(t)); + + memcpy(LX_TASK(t), &init_task, sizeof(struct task_struct)); + + /* nice: Linux backreferences a task`s thread_info from the + * task struct (which in turn can be found using the + * thread_info...) */ + LX_TASK(t)->stack = &LX_THREAD(t); + + /* initialize this thread's sleep lock */ + SLEEP_LOCK(t) = ddekit_sem_init(0); + + return t; +} + +/* Process setup for worker threads */ +int l4dde26_process_add_worker(void) +{ + dde26_thread_data *cur = init_dde26_thread(); + + /* If this function is called for a kernel_thread, the thread already has + * been set up and we just need to store a reference to the ddekit struct. + * However, this function may also be called directly to turn an L4 thread + * into a DDE thread. Then, we need to initialize here. */ + cur->_ddekit_thread = ddekit_thread_myself(); + if (cur->_ddekit_thread == NULL) + cur->_ddekit_thread = ddekit_thread_setup_myself(".dde26_thread"); + Assert(cur->_ddekit_thread); + + ddekit_thread_set_my_data(cur); + + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + /* Linux' default is to have this set to 1 initially and let the + * scheduler set this to 0 later on. + */ + current_thread_info()->preempt_count = 0; + + return 0; +} + + +/** + * Add an already existing DDEKit thread to the set of threads known to the + * Linux environment. This is used for the timer thread, which is actually a + * DDEKit thread, but Linux code shall see it as a Linux thread as well. + */ +int l4dde26_process_from_ddekit(ddekit_thread_t *t) +{ + Assert(t); + + dde26_thread_data *cur = init_dde26_thread(); + cur->_ddekit_thread = t; + ddekit_thread_set_data(t, cur); + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + return 0; +} + +/** Function to initialize the first DDE process. + */ +int __init l4dde26_process_init(void) +{ + ddekit_lock_init_unlocked(&_pid_task_list_lock); + + int kthreadd_pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); + kthreadd_task = find_task_by_pid(kthreadd_pid); + + l4dde26_process_add_worker(); + + return 0; +} + +DEFINE_PER_CPU(int, cpu_number); + +//dde_process_initcall(l4dde26_process_init); diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/res.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/res.c.svn-base new file mode 100644 index 00000000..fbd2d09b --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/res.c.svn-base @@ -0,0 +1,180 @@ +#include "local.h" + +#include + +/** Request an IO port region. + * + * \param start start port + * \param n number of ports + * \param name name of allocator (unused) + * + * \return NULL error + * \return !=NULL success + * + * \bug Since no one in Linux uses this function's return value, + * we do not allocate and fill a resource struct. + */ +static struct resource *l4dde26_request_region(resource_size_t start, + resource_size_t n, + const char *name) +{ + int err = ddekit_request_io(start, n); + + if (err) + return NULL; + + return (struct resource *)1; +} + + +/** List of memory regions that have been requested. This is used to + * perform ioremap() and iounmap() + */ +static LIST_HEAD(dde_mem_regions); + +/** va->pa mapping used to store memory regions */ +struct dde_mem_region { + ddekit_addr_t pa; + ddekit_addr_t va; + unsigned int size; + struct list_head list; +}; + +void __iomem * ioremap(unsigned long phys_addr, unsigned long size); + +/** Request an IO memory region. + * + * \param start start address + * \param n size of memory area + * \param name name of allocator (unused) + * + * \return NULL error + * \return !=NULL success + * + * \bug Since no one in Linux uses this function's return value, + * we do not allocate and fill a resource struct. + */ +static struct resource *l4dde26_request_mem_region(resource_size_t start, + resource_size_t n, + const char *name) +{ + ddekit_addr_t va = 0; + struct dde_mem_region *mreg; + + // do not a resource request twice + if (ioremap(start, n)) + return (struct resource *)1; + + int i = ddekit_request_mem(start, n, &va); + + if (i) { + ddekit_printf("request_mem_region() failed (start %lx, size %x)", start, n); + return NULL; + } + + mreg = kmalloc(sizeof(struct dde_mem_region), GFP_KERNEL); + Assert(mreg); + + mreg->pa = start; + mreg->va = va; + mreg->size = n; + list_add(&mreg->list, &dde_mem_regions); + +#if 0 + ddekit_pgtab_set_region_with_size((void *)va, start, n, PTE_TYPE_OTHER); +#endif + + return (struct resource *)1; +} + + +struct resource * __request_region(struct resource *parent, + resource_size_t start, + resource_size_t n, + const char *name, int flags) +{ + Assert(parent); + Assert(parent->flags & IORESOURCE_IO || parent->flags & IORESOURCE_MEM); + + switch (parent->flags) + { + case IORESOURCE_IO: + return l4dde26_request_region(start, n, name); + case IORESOURCE_MEM: + return l4dde26_request_mem_region(start, n, name); + } + + return NULL; +} + + +/** Release IO port region. + */ +static void l4dde26_release_region(resource_size_t start, resource_size_t n) +{ + /* FIXME: we need a list of "struct resource"s that have been + * allocated by request_region() and then need to + * free this stuff here! */ + ddekit_release_io(start, n); +} + + +/** Release IO memory region. + */ +static void l4dde26_release_mem_region(resource_size_t start, resource_size_t n) +{ + ddekit_release_mem(start, n); + ddekit_pgtab_clear_region((void *)start, PTE_TYPE_OTHER); +} + + +int __check_region(struct resource *root, resource_size_t s, resource_size_t n) +{ + WARN_UNIMPL; + return -1; +} + +void __release_region(struct resource *root, resource_size_t start, + resource_size_t n) +{ + switch (root->flags) + { + case IORESOURCE_IO: + return l4dde26_release_region(start, n); + case IORESOURCE_MEM: + return l4dde26_release_mem_region(start, n); + } +} + + +/** Map physical I/O region into virtual address space. + * + * For our sake, this only returns the virtual address belonging to + * the physical region, since we don't manage page tables ourselves. + */ +void __iomem * ioremap(unsigned long phys_addr, unsigned long size) +{ + struct list_head *pos, *head; + head = &dde_mem_regions; + + list_for_each(pos, head) { + struct dde_mem_region *mreg = list_entry(pos, struct dde_mem_region, + list); + if (mreg->pa <= phys_addr && mreg->pa + mreg->size >= phys_addr + size) + return (void *)(mreg->va + (phys_addr - mreg->pa)); + } + + return NULL; +} + + +void __iomem * ioremap_nocache(unsigned long offset, unsigned long size) +{ + return ioremap(offset, size); +} + + +void iounmap(volatile void __iomem *addr) +{ + WARN_UNIMPL; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/sched.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/sched.c.svn-base new file mode 100644 index 00000000..b38520c6 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/sched.c.svn-base @@ -0,0 +1,155 @@ +#include "local.h" + +#include + +DEFINE_RWLOCK(tasklist_lock); + +asmlinkage void preempt_schedule(void) +{ + WARN_UNIMPL; +} + + +/* Our version of scheduler invocation. + * + * Scheduling is performed by Fiasco, so we don't care about it as long as + * a thread is running. If a task becomes TASK_INTERRUPTIBLE or + * TASK_UNINTERRUPTIBLE, we make sure that the task does not become + * scheduled by locking the task's sleep lock. + */ +asmlinkage void schedule(void) +{ + dde26_thread_data *t = lxtask_to_ddethread(current); + + switch (current->state) { + case TASK_RUNNING: + ddekit_thread_schedule(); + break; + case TASK_INTERRUPTIBLE: + case TASK_UNINTERRUPTIBLE: + ddekit_sem_down(SLEEP_LOCK(t)); + break; + default: + panic("current->state = %d --- unknown state\n", current->state); + } +} + + +/** yield the current processor to other threads. + * + * this is a shortcut for kernel-space yielding - it marks the + * thread runnable and calls sys_sched_yield(). + */ +void __sched yield(void) +{ + set_current_state(TASK_RUNNING); + ddekit_yield(); +} + + +/*** + * try_to_wake_up - wake up a thread + * @p: the to-be-woken-up thread + * @state: the mask of task states that can be woken + * @sync: do a synchronous wakeup? + */ +int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) +{ + Assert(p); + dde26_thread_data *t = lxtask_to_ddethread(p); + + Assert(t); + Assert(SLEEP_LOCK(t)); + + p->state = TASK_RUNNING; + ddekit_sem_up(SLEEP_LOCK(t)); + + return 0; +} + + +static void process_timeout(unsigned long data) +{ + wake_up_process((struct task_struct *)data); +} + + +signed long __sched schedule_timeout(signed long timeout) +{ + struct timer_list timer; + unsigned long expire = timeout + jiffies; + + setup_timer(&timer, process_timeout, (unsigned long)current); + timer.expires = expire; + + switch(timeout) + { + /* + * Hah! + * + * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule + * the CPU away without a bound on the timeout. In this case the return + * value will be %MAX_SCHEDULE_TIMEOUT. + */ + case MAX_SCHEDULE_TIMEOUT: + schedule(); + break; + default: + add_timer(&timer); + schedule(); + del_timer(&timer); + break; + } + + timeout = expire - jiffies; + + return timeout < 0 ? 0 : timeout; +} + + +signed long __sched schedule_timeout_interruptible(signed long timeout) +{ + __set_current_state(TASK_INTERRUPTIBLE); + return schedule_timeout(timeout); +} + + +signed long __sched schedule_timeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_timeout(timeout); +} + +/** Tasks may be forced to run only on a certain no. of CPUs. Since + * we only emulate a SMP-environment for the sake of having multiple + * threads, we do not need to implement this. + */ +int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) +{ + return 0; +} + +void set_user_nice(struct task_struct *p, long nice) +{ + //WARN_UNIMPL; +} + +void __sched io_schedule(void) +{ + WARN_UNIMPL; +} + +long __sched io_schedule_timeout(long timeout) +{ + WARN_UNIMPL; + return -1; +} + +extern int sched_setscheduler_nocheck(struct task_struct *t, int flags, + struct sched_param *p) +{ + WARN_UNIMPL; + return -1; +} + +void ignore_signals(struct task_struct *t) { } diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/signal.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/signal.c.svn-base new file mode 100644 index 00000000..bd0bc0a7 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/signal.c.svn-base @@ -0,0 +1,24 @@ +#include "local.h" + +/****************************************************************************** + ** Dummy signal implementation. ** + ** DDE does not provide its own signal implementation. To make it compile, ** + ** we provide dummy versions of signalling functions here. If later on ** + ** someone *REALLY* wants to use signals in the DDE context, he might ** + ** erase this file and use something like the L4 signalling library for ** + ** such purposes. ** +*******************************************************************************/ + +int sigprocmask(int how, sigset_t *set, sigset_t *oldset) +{ + return 0; +} + +void flush_signals(struct task_struct *t) +{ +} + +int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) +{ + return 0; +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/smp.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/smp.c.svn-base new file mode 100644 index 00000000..1ebf08c2 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/smp.c.svn-base @@ -0,0 +1,37 @@ +#include + +#include "local.h" + +static struct cpumask _possible = CPU_MASK_ALL; +static struct cpumask _online = CPU_MASK_CPU0; +static struct cpumask _present = CPU_MASK_CPU0; +static struct cpumask _active = CPU_MASK_CPU0; + +const struct cpumask *const cpu_possible_mask = &_possible; +const struct cpumask *const cpu_online_mask = &_online; +const struct cpumask *const cpu_present_mask = &_present; +const struct cpumask *const cpu_active_mask = &_active; + +cpumask_t cpu_mask_all = CPU_MASK_ALL; +int nr_cpu_ids = NR_CPUS; +const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); + +/* cpu_bit_bitmap[0] is empty - so we can back into it */ +#define MASK_DECLARE_1(x) [x+1][0] = 1UL << (x) +#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1) +#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2) +#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4) + +const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = { + MASK_DECLARE_8(0), MASK_DECLARE_8(8), + MASK_DECLARE_8(16), MASK_DECLARE_8(24), +#if BITS_PER_LONG > 32 + MASK_DECLARE_8(32), MASK_DECLARE_8(40), + MASK_DECLARE_8(48), MASK_DECLARE_8(56), +#endif +}; + +void __smp_call_function_single(int cpuid, struct call_single_data *data) +{ + data->func(data->info); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/softirq.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/softirq.c.svn-base new file mode 100644 index 00000000..21b36d17 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/softirq.c.svn-base @@ -0,0 +1,267 @@ +#include "local.h" + +#include + +/* There are at most 32 softirqs in Linux, but only 6 are really used. */ +#define NUM_SOFTIRQS 6 + +DECLARE_INITVAR(dde26_softirq); + +/* softirq threads and their wakeup semaphores */ +ddekit_thread_t *dde_softirq_thread; +ddekit_sem_t *dde_softirq_sem; + +/* struct tasklet_head is not defined in a header in Linux 2.6 */ +struct tasklet_head +{ + struct tasklet_struct *list; + ddekit_lock_t lock; /* list lock */ +}; + +/* What to do if a softirq occurs. */ +static struct softirq_action softirq_vec[32]; + +/* tasklet queues for each softirq thread */ +struct tasklet_head tasklet_vec; +struct tasklet_head tasklet_hi_vec; + +void open_softirq(int nr, void (*action)(struct softirq_action*)) +{ + softirq_vec[nr].action = action; +} + +static void raise_softirq_irqoff_cpu(unsigned int nr, unsigned int cpu) +{ + CHECK_INITVAR(dde26_softirq); + + /* mark softirq scheduled */ + __raise_softirq_irqoff(nr); + /* wake softirq thread */ + ddekit_sem_up(dde_softirq_sem); +} + +void raise_softirq_irqoff(unsigned int nr) +{ + raise_softirq_irqoff_cpu(nr, 0); +} + +void raise_softirq(unsigned int nr) +{ + unsigned long flags; + + local_irq_save(flags); + raise_softirq_irqoff(nr); + local_irq_restore(flags); +} + +/** + * Initialize tasklet. + */ +void tasklet_init(struct tasklet_struct *t, + void (*func)(unsigned long), unsigned long data) +{ + t->next = NULL; + t->state = 0; + atomic_set(&t->count, 0); + t->func = func; + t->data = data; +} + +/* enqueue tasklet */ +static void __tasklet_enqueue(struct tasklet_struct *t, + struct tasklet_head *listhead) +{ + ddekit_lock_lock(&listhead->lock); + t->next = listhead->list; + listhead->list = t; + ddekit_lock_unlock(&listhead->lock); +} + +void __tasklet_schedule(struct tasklet_struct *t) +{ + unsigned long flags; + + CHECK_INITVAR(dde26_softirq); + + local_irq_save(flags); + + __tasklet_enqueue(t, &tasklet_vec); + /* raise softirq */ + raise_softirq_irqoff_cpu(TASKLET_SOFTIRQ, 0); + + local_irq_restore(flags); +} + +void __tasklet_hi_schedule(struct tasklet_struct *t) +{ + unsigned long flags; + + CHECK_INITVAR(dde26_softirq); + + local_irq_save(flags); + __tasklet_enqueue(t, &tasklet_hi_vec); + raise_softirq_irqoff_cpu(HI_SOFTIRQ, 0); + local_irq_restore(flags); +} + +/* Execute tasklets */ +static void tasklet_action(struct softirq_action *a) +{ + struct tasklet_struct *list; + + ddekit_lock_lock(&tasklet_vec.lock); + list = tasklet_vec.list; + tasklet_vec.list = NULL; + ddekit_lock_unlock(&tasklet_vec.lock); + + while (list) { + struct tasklet_struct *t = list; + + list = list->next; + + if (tasklet_trylock(t)) { + if (!atomic_read(&t->count)) { + if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + BUG(); + t->func(t->data); + tasklet_unlock(t); + continue; + } + tasklet_unlock(t); + } + + ddekit_lock_lock(&tasklet_vec.lock); + t->next = tasklet_vec.list; + tasklet_vec.list = t; + raise_softirq_irqoff_cpu(TASKLET_SOFTIRQ, 0); + ddekit_lock_unlock(&tasklet_vec.lock); + } +} + + +static void tasklet_hi_action(struct softirq_action *a) +{ + struct tasklet_struct *list; + + ddekit_lock_lock(&tasklet_hi_vec.lock); + list = tasklet_hi_vec.list; + tasklet_hi_vec.list = NULL; + ddekit_lock_unlock(&tasklet_hi_vec.lock); + + while (list) { + struct tasklet_struct *t = list; + + list = list->next; + + if (tasklet_trylock(t)) { + if (!atomic_read(&t->count)) { + if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + BUG(); + t->func(t->data); + tasklet_unlock(t); + continue; + } + tasklet_unlock(t); + } + + ddekit_lock_lock(&tasklet_hi_vec.lock); + t->next = tasklet_hi_vec.list; + tasklet_hi_vec.list = t; + raise_softirq_irqoff_cpu(HI_SOFTIRQ, 0); + ddekit_lock_unlock(&tasklet_hi_vec.lock); + } +} + + +#define MAX_SOFTIRQ_RETRIES 10 + +/** Run softirq handlers + */ +void __do_softirq(void) +{ + int retries = MAX_SOFTIRQ_RETRIES; + do { + struct softirq_action *h = softirq_vec; + unsigned long pending = local_softirq_pending(); + + /* reset softirq count */ + set_softirq_pending(0); + + /* While we have a softirq pending... */ + while (pending) { + /* need to execute current softirq? */ + if (pending & 1) + h->action(h); + /* try next softirq */ + h++; + /* remove pending flag for last softirq */ + pending >>= 1; + } + + /* Somebody might have scheduled another softirq in between + * (e.g., an IRQ thread or another tasklet). */ + } while (local_softirq_pending() && --retries); + +} + + +void do_softirq(void) +{ + unsigned long flags; + + local_irq_save(flags); + if (local_softirq_pending()) + __do_softirq(); + local_irq_restore(flags); +} + +/** Softirq thread function. + * + * Once started, a softirq thread waits for tasklets to be scheduled + * and executes them. + * + * \param arg # of this softirq thread so that it grabs the correct lock + * if multiple softirq threads are running. + */ +void l4dde26_softirq_thread(void *arg) +{ + printk("Softirq daemon starting\n"); + l4dde26_process_add_worker(); + + /* This thread will always be in a softirq, so set the + * corresponding flag right now. + */ + preempt_count() |= SOFTIRQ_MASK; + + while(1) { + ddekit_sem_down(dde_softirq_sem); + do_softirq(); + } +} + +/** Initialize softirq subsystem. + * + * Start NUM_SOFTIRQ_THREADS threads executing the \ref l4dde26_softirq_thread + * function. + */ +void l4dde26_softirq_init(void) +{ + char name[20]; + + dde_softirq_sem = ddekit_sem_init(0); + + set_softirq_pending(0); + + ddekit_lock_init_unlocked(&tasklet_vec.lock); + ddekit_lock_init_unlocked(&tasklet_hi_vec.lock); + + snprintf(name, 20, ".softirqd"); + dde_softirq_thread = ddekit_thread_create( + l4dde26_softirq_thread, + NULL, name); + + open_softirq(TASKLET_SOFTIRQ, tasklet_action); + open_softirq(HI_SOFTIRQ, tasklet_hi_action); + + INITIALIZE_INITVAR(dde26_softirq); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/timer.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/timer.c.svn-base new file mode 100644 index 00000000..ea04b67e --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/timer.c.svn-base @@ -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); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmalloc.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmalloc.c.svn-base new file mode 100644 index 00000000..134b80c3 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmalloc.c.svn-base @@ -0,0 +1,30 @@ +/****************************************************************************** + * Bjoern Doebel * + * * + * (c) 2005 - 2007 Technische Universitaet Dresden * + * This file is part of DROPS, which is distributed under the terms of the * + * GNU General Public License 2. Please see the COPYING file for details. * + ******************************************************************************/ + +/* + * \brief vmalloc implementation + * \author Bjoern Doebel + * \date 2007-07-30 + */ + +/* Linux */ +#include + +/* DDEKit */ +#include +#include + +void *vmalloc(unsigned long size) +{ + return ddekit_simple_malloc(size); +} + +void vfree(const void *addr) +{ + ddekit_simple_free((void*)addr); +} diff --git a/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmstat.c.svn-base b/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmstat.c.svn-base new file mode 100644 index 00000000..2e87389e --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/.svn/text-base/vmstat.c.svn-base @@ -0,0 +1,34 @@ +#include "local.h" + +#include + +atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; + + +void dec_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + + +void inc_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + + +void __inc_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + +void __get_zone_counts(unsigned long *active, unsigned long *inactive, + unsigned long *free, struct pglist_data *pgdat) +{ + WARN_UNIMPL; +} + +void __dec_zone_state(struct zone *zone, enum zone_stat_item item) +{ + WARN_UNIMPL; +} diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c new file mode 100644 index 00000000..81c4feea --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c @@ -0,0 +1,66 @@ +#include "local.h" + +#include + +/* IRQ lock reference counter */ +static atomic_t _refcnt = ATOMIC_INIT(0); + +/* Check whether IRQs are currently disabled. + * + * This is the case, if flags is greater than 0. + */ + +int raw_irqs_disabled_flags(unsigned long flags) +{ + return ((int)flags > 0); +} + +/* Store the current flags state. + * + * This is done by returning the current refcnt. + * + * XXX: Up to now, flags was always 0 at this point and + * I assume that this is always the case. Prove? + */ +unsigned long __raw_local_save_flags(void) +{ + return (unsigned long)atomic_read(&_refcnt); +} + +/* Restore IRQ state. */ +void raw_local_irq_restore(unsigned long flags) +{ + atomic_set(&_refcnt, flags); +} + +/* Disable IRQs by grabbing the IRQ lock. */ +void raw_local_irq_disable(void) +{ + atomic_inc(&_refcnt); +} + +/* Unlock the IRQ lock until refcnt is 0. */ +void raw_local_irq_enable(void) +{ + atomic_set(&_refcnt, 0); +} + + +void raw_safe_halt(void) +{ + WARN_UNIMPL; +} + + +void halt(void) +{ + WARN_UNIMPL; +} + +/* These functions are empty for DDE. Every DDE thread is a separate + * "virtual" CPU. Therefore there is no need to en/disable bottom halves. + */ +void local_bh_disable(void) {} +void __local_bh_enable(void) {} +void _local_bh_enable(void) {} +void local_bh_enable(void) {} diff --git a/libdde_linux26/lib/src/arch/l4/fs.c b/libdde_linux26/lib/src/arch/l4/fs.c new file mode 100644 index 00000000..db452949 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/fs.c @@ -0,0 +1,111 @@ +#include "local.h" + +#include +#include +#include + +/* + * Some subsystems, such as the blockdev layer, implement their data + * hierarchy as a pseudo file system. To not incorporate the complete + * Linux VFS implementation, we cut this down to an own one only for + * pseudo file systems. + */ +static LIST_HEAD(dde_vfs_mounts); + +#define MAX_RA_PAGES 1 + +void default_unplug_io_fn(struct backing_dev_info *bdi, struct page* p) +{ +} + +struct backing_dev_info default_backing_dev_info = { + .ra_pages = MAX_RA_PAGES, + .state = 0, + .capabilities = BDI_CAP_MAP_COPY, + .unplug_io_fn = default_unplug_io_fn, +}; + +int seq_printf(struct seq_file *m, const char *f, ...) +{ + WARN_UNIMPL; + return 0; +} + +int generic_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + WARN_UNIMPL; + return 0; +} + + +/************************************** + * Filemap stuff * + **************************************/ +struct page * find_get_page(struct address_space *mapping, unsigned long offset) +{ + WARN_UNIMPL; + return NULL; +} + +void unlock_page(struct page *page) +{ + WARN_UNIMPL; +} + +int test_set_page_writeback(struct page *page) +{ + WARN_UNIMPL; + return 0; +} + +void end_page_writeback(struct page *page) +{ + WARN_UNIMPL; +} + +void do_invalidatepage(struct page *page, unsigned long offset) +{ + WARN_UNIMPL; +} + +int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page) +{ + WARN_UNIMPL; + return 0; +} + +static struct vfsmount *dde_kern_mount(struct file_system_type *type, + int flags, const char *name, + void *data) +{ + struct list_head *pos, *head; + int error; + + head = &dde_vfs_mounts; + __list_for_each(pos, head) { + struct vfsmount *mnt = list_entry(pos, struct vfsmount, next); + if (strcmp(name, mnt->name) == 0) { + printk("FS type %s already mounted!?\n", name); + BUG(); + return NULL; + } + } + + struct vfsmount *m = kzalloc(sizeof(*m), GFP_KERNEL); + m->fs_type = type; + m->name = kmalloc(strlen(name) + 1, GFP_KERNEL); + memcpy(m->name, name, strlen(name) + 1); + + error = type->get_sb(type, flags, name, data, m); + BUG_ON(error); + + list_add_tail(&m->next, &dde_vfs_mounts); + + return m; +} + +struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) +{ + return dde_kern_mount(type, 0, type->name, NULL); +} diff --git a/libdde_linux26/lib/src/arch/l4/hw-helpers.c b/libdde_linux26/lib/src/arch/l4/hw-helpers.c new file mode 100644 index 00000000..555406c9 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/hw-helpers.c @@ -0,0 +1,12 @@ +#include "local.h" + +#include + +note_buf_t *crash_notes = NULL; + +void touch_nmi_watchdog(void) +{ + WARN_UNIMPL; +} + +unsigned long pci_mem_start = 0xABCDABCD; diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c new file mode 100644 index 00000000..e89ef27f --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -0,0 +1,33 @@ +#include "local.h" + +#include +#include + +#define DEBUG_PCI(msg, ...) ddekit_printf( "\033[33m"msg"\033[0m\n", ##__VA_ARGS__) + +/* Didn't know where to put this. */ +unsigned long __per_cpu_offset[NR_CPUS]; + +extern void driver_init(void); +extern int classes_init(void); + +void __init __attribute__((used)) l4dde26_init(void) +{ + /* first, initialize DDEKit */ + ddekit_init(); + + l4dde26_kmalloc_init(); + + /* Init Linux driver framework before trying to add PCI devs to the bus */ + driver_init(); + + printk("Initialized DDELinux 2.6\n"); +} + +void l4dde26_do_initcalls(void) +{ + /* finally, let DDEKit perform all the initcalls */ + ddekit_do_initcalls(); +} + +dde_initcall(l4dde26_init); diff --git a/libdde_linux26/lib/src/arch/l4/init_task.c b/libdde_linux26/lib/src/arch/l4/init_task.c new file mode 100644 index 00000000..685373d1 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/init_task.c @@ -0,0 +1,131 @@ +#include "local.h" + +//#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* init task */ +struct task_struct init_task; + +/* From kernel/pid.c */ +#define BITS_PER_PAGE (PAGE_SIZE*8) +#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) + +/* From init/main.c */ +enum system_states system_state; +EXPORT_SYMBOL(system_state); + +struct fs_struct init_fs = { + .count = ATOMIC_INIT(1), + .lock = __RW_LOCK_UNLOCKED(init_fs.lock), + .umask = 0022, +}; + +struct files_struct init_files = { + .count = ATOMIC_INIT(1), + .fdt = &init_files.fdtab, + .fdtab = { + .max_fds = NR_OPEN_DEFAULT, + .fd = &init_files.fd_array[0], + .close_on_exec = (fd_set *)&init_files.close_on_exec_init, + .open_fds = (fd_set *)&init_files.open_fds_init, + .rcu = RCU_HEAD_INIT, + }, + .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), +}; + +struct signal_struct init_signals = INIT_SIGNALS(init_signals); +struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); +pgd_t swapper_pg_dir[PTRS_PER_PGD]; +union thread_union init_thread_union = { INIT_THREAD_INFO(init_task) }; +struct group_info init_groups = {.usage = ATOMIC_INIT(2)}; + +struct user_struct root_user = { + .__count = ATOMIC_INIT(1), + .processes = ATOMIC_INIT(1), + .files = ATOMIC_INIT(0), + .sigpending = ATOMIC_INIT(0), + .mq_bytes = 0, + .locked_shm = 0, +}; + +/* + * PID-map pages start out as NULL, they get allocated upon + * first use and are never deallocated. This way a low pid_max + * value does not cause lots of bitmaps to be allocated, but + * the scheme scales to up to 4 million PIDs, runtime. + */ +struct pid_namespace init_pid_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, + .pidmap = { + [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } + }, + .last_pid = 0, + .level = 0, + .child_reaper = &init_task, +}; +EXPORT_SYMBOL_GPL(init_pid_ns); + +struct net init_net __attribute__((weak)); + +struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); + +struct ipc_namespace init_ipc_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, +}; + +struct user_namespace init_user_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, +}; + + +struct uts_namespace init_uts_ns = { + .kref = { + .refcount = ATOMIC_INIT(2), + }, + .name = { + .sysname = "L4/DDE", + .nodename = "", + .release = "2.6", + .version = "25", + .machine = "", + .domainname = "", + }, +}; + +struct exec_domain default_exec_domain = { + .name = "Linux", /* name */ + .handler = NULL, /* no signaling! */ + .pers_low = 0, /* PER_LINUX personality. */ + .pers_high = 0, /* PER_LINUX personality. */ + .signal_map = 0, /* Identity map signals. */ + .signal_invmap = 0, /* - both ways. */ +}; + +/* copy of the initial task struct */ +struct task_struct init_task = INIT_TASK(init_task); +/* copy of the initial thread info (which contains init_task) */ +struct thread_info init_thread = INIT_THREAD_INFO(init_task); + +long do_no_restart_syscall(struct restart_block *param) +{ + return -EINTR; +} diff --git a/libdde_linux26/lib/src/arch/l4/inodes.c b/libdde_linux26/lib/src/arch/l4/inodes.c new file mode 100644 index 00000000..9ef02ed5 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/inodes.c @@ -0,0 +1,311 @@ +/** lib/src/arch/l4/inodes.c + * + * Assorted dummies implementing inode and superblock access functions, + * which are used by the block layer stuff, but not needed in DDE_Linux. + */ + +#include "local.h" + +#include +#include +#include + +/* + * Linux' global list of all super blocks. + */ +LIST_HEAD(super_blocks); + +/********************************** + * Inode stuff * + **********************************/ + +struct inode* new_inode(struct super_block *sb) +{ + if (sb->s_op->alloc_inode) + return sb->s_op->alloc_inode(sb); + + return kzalloc(sizeof(struct inode), GFP_KERNEL); +} + +void __mark_inode_dirty(struct inode *inode, int flags) +{ + WARN_UNIMPL; +} + +void iput(struct inode *inode) +{ + WARN_UNIMPL; +} + +void generic_delete_inode(struct inode *inode) +{ + WARN_UNIMPL; +} + +int invalidate_inodes(struct super_block * sb) +{ + WARN_UNIMPL; + return 0; +} + +void truncate_inode_pages(struct address_space *mapping, loff_t lstart) +{ + WARN_UNIMPL; +} + +void touch_atime(struct vfsmount *mnt, struct dentry *dentry) +{ + WARN_UNIMPL; +} + +/********************************** + * Superblock stuff * + **********************************/ + +struct super_block * get_super(struct block_device *bdev) +{ + WARN_UNIMPL; + return NULL; +} + +int simple_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + WARN_UNIMPL; + return 0; +} + +void kill_anon_super(struct super_block *sb) +{ + WARN_UNIMPL; +} + +void shrink_dcache_sb(struct super_block * sb) +{ + WARN_UNIMPL; +} + +void drop_super(struct super_block *sb) +{ + WARN_UNIMPL; +} + +struct inode_operations empty_iops = { }; +struct file_operations empty_fops = { }; + +/**! Alloc and init a new inode. + * + * Basically stolen from linux/fs/inode.c:alloc_inode() + */ +static struct inode *dde_alloc_inode(struct super_block *sb) +{ + struct inode *inode; + + if (sb->s_op->alloc_inode) + inode = sb->s_op->alloc_inode(sb); + else + inode = kzalloc(sizeof(*inode), GFP_KERNEL); + + if (inode) { + inode->i_sb = sb; + inode->i_blkbits = sb->s_blocksize_bits; + inode->i_flags = 0; + atomic_set(&inode->i_count, 1); + inode->i_op = &empty_iops; + inode->i_fop = &empty_fops; + inode->i_nlink = 1; + atomic_set(&inode->i_writecount, 0); + inode->i_size = 0; + inode->i_blocks = 0; + inode->i_bytes = 0; + inode->i_generation = 0; + inode->i_pipe = NULL; + inode->i_bdev = NULL; + inode->i_cdev = NULL; + inode->i_rdev = 0; + inode->dirtied_when = 0; + inode->i_private = NULL; + } + + return inode; +} + + +void __iget(struct inode *inode) +{ + atomic_inc(&inode->i_count); +} + + +static struct inode *dde_new_inode(struct super_block *sb, struct list_head *head, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), void *data) +{ + struct inode *ret = dde_alloc_inode(sb); + int err = 0; + + if (set) + err = set(ret, data); + + BUG_ON(err); + + __iget(ret); + ret->i_state = I_LOCK|I_NEW; + + list_add_tail(&ret->i_sb_list, &sb->s_inodes); + + return ret; +} + + +struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), void *data) +{ + struct inode *inode = NULL; + struct list_head *p; + + list_for_each(p, &sb->s_inodes) { + struct inode *i = list_entry(p, struct inode, i_sb_list); + if (test) { + if (!test(i, data)) { + DEBUG_MSG("test false"); + continue; + } + else { + inode = i; + break; + } + } + } + + if (inode) + return inode; + + return dde_new_inode(sb, &sb->s_inodes, test, set, data); +} + +void unlock_new_inode(struct inode *inode) +{ + inode->i_state &= ~(I_LOCK | I_NEW); + wake_up_bit(&inode->i_state, __I_LOCK); +} + +struct super_block *sget(struct file_system_type *type, + int (*test)(struct super_block *, void*), + int (*set)(struct super_block *, void*), + void *data) +{ + struct super_block *s = NULL; + struct list_head *p; + int err; + + if (test) { + list_for_each(p, &type->fs_supers) { + struct super_block *block = list_entry(p, + struct super_block, + s_instances); + if (!test(block, data)) + continue; + return block; + } + } + + s = kzalloc(sizeof(*s), GFP_KERNEL); + BUG_ON(!s); + + INIT_LIST_HEAD(&s->s_dirty); + INIT_LIST_HEAD(&s->s_io); + INIT_LIST_HEAD(&s->s_files); + INIT_LIST_HEAD(&s->s_instances); + INIT_HLIST_HEAD(&s->s_anon); + INIT_LIST_HEAD(&s->s_inodes); + init_rwsem(&s->s_umount); + mutex_init(&s->s_lock); + lockdep_set_class(&s->s_umount, &type->s_umount_key); + /* + * The locking rules for s_lock are up to the + * filesystem. For example ext3fs has different + * lock ordering than usbfs: + */ + lockdep_set_class(&s->s_lock, &type->s_lock_key); + down_write(&s->s_umount); + s->s_count = S_BIAS; + atomic_set(&s->s_active, 1); + mutex_init(&s->s_vfs_rename_mutex); + mutex_init(&s->s_dquot.dqio_mutex); + mutex_init(&s->s_dquot.dqonoff_mutex); + init_rwsem(&s->s_dquot.dqptr_sem); + init_waitqueue_head(&s->s_wait_unfrozen); + s->s_maxbytes = MAX_NON_LFS; +#if 0 + s->dq_op = sb_dquot_ops; + s->s_qcop = sb_quotactl_ops; + s->s_op = &default_op; +#endif + s->s_time_gran = 1000000000; + + err = set(s, data); + BUG_ON(err); + + s->s_type = type; + strlcpy(s->s_id, type->name, sizeof(s->s_id)); + list_add_tail(&s->s_list, &super_blocks); + list_add(&s->s_instances, &type->fs_supers); + __module_get(type->owner); + return s; +} + +int set_anon_super(struct super_block *s, void *data) +{ + WARN_UNIMPL; + return 0; +} + +int get_sb_pseudo(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, unsigned long magic, + struct vfsmount *mnt) +{ + struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); + struct super_operations default_ops = {}; + struct inode *root = NULL; + struct dentry *dentry = NULL; + struct qstr d_name = {.name = name, .len = strlen(name)}; + + BUG_ON(IS_ERR(s)); + + s->s_flags = MS_NOUSER; + s->s_maxbytes = ~0ULL; + s->s_blocksize = 1024; + s->s_blocksize_bits = 10; + s->s_magic = magic; + s->s_op = ops ? ops : &default_ops; + s->s_time_gran = 1; + root = new_inode(s); + + BUG_ON(!root); + + root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; + root->i_uid = root->i_gid = 0; +#if 0 + root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; + dentry = d_alloc(NULL, &d_name); + dentry->d_sb = s; + dentry->d_parent = dentry; + d_instantiate(dentry, root); +#endif + s->s_root = dentry; + s->s_flags |= MS_ACTIVE; + + mnt->mnt_sb = s; + mnt->mnt_root = dget(s->s_root); + + DEBUG_MSG("root mnt sb @ %p", mnt->mnt_sb); + + return 0; +} + +void inode_init_once(struct inode *inode) +{ + WARN_UNIMPL; +} + diff --git a/libdde_linux26/lib/src/arch/l4/irq.c b/libdde_linux26/lib/src/arch/l4/irq.c new file mode 100644 index 00000000..0e565e54 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/irq.c @@ -0,0 +1,247 @@ +/* + * \brief Hardware-interrupt support + * \author Christian Helmuth + * \date 2007-02-12 + * + * + * + * XXX Consider support for IRQ_HANDLED and friends (linux/irqreturn.h) + */ + +/* Linux */ +#include +#include /* memset() */ + +/* DDEKit */ +#include +#include + +/* local */ +#include "dde26.h" +#include "local.h" + +/* dummy */ +irq_cpustat_t irq_stat[CONFIG_NR_CPUS]; + +/** + * IRQ handling data + */ +static struct dde_irq +{ + unsigned irq; /* IRQ number */ + unsigned count; /* usage count */ + int shared; /* shared IRQ */ + struct ddekit_thread *thread; /* DDEKit interrupt thread */ + struct irqaction *action; /* Linux IRQ action */ + + struct dde_irq *next; /* next DDE IRQ */ +} *used_irqs; + + +static void irq_thread_init(void *p) { + l4dde26_process_add_worker(); } + + +extern ddekit_sem_t *dde_softirq_sem; +static void irq_handler(void *arg) +{ + struct dde_irq *irq = arg; + struct irqaction *action; + +#if 0 + DEBUG_MSG("irq 0x%x", irq->irq); +#endif + /* interrupt occurred - call all handlers */ + for (action = irq->action; action; action = action->next) { + irqreturn_t r = action->handler(action->irq, action->dev_id); +#if 0 + DEBUG_MSG("return: %s", r == IRQ_HANDLED ? "IRQ_HANDLED" : r == IRQ_NONE ? "IRQ_NONE" : "??"); +#endif + } + + /* upon return we check for pending soft irqs */ + if (local_softirq_pending()) + ddekit_sem_up(dde_softirq_sem); +} + + +/***************************** + ** IRQ handler bookkeeping ** + *****************************/ + +/** + * Claim IRQ + * + * \return usage counter or negative error code + * + * FIXME list locking + * FIXME are there more races? + */ +static int claim_irq(struct irqaction *action) +{ + int shared = action->flags & IRQF_SHARED ? 1 : 0; + struct dde_irq *irq; + + /* check if IRQ already used */ + for (irq = used_irqs; irq; irq = irq->next) + if (irq->irq == action->irq) break; + + /* we have to setup IRQ handling */ + if (!irq) { + /* allocate and initalize new descriptor */ + irq = ddekit_simple_malloc(sizeof(*irq)); + if (!irq) return -ENOMEM; + memset(irq, 0, sizeof(*irq)); + + irq->irq = action->irq; + irq->shared = shared; + irq->next = used_irqs; + used_irqs = irq; + + /* attach to interrupt */ + irq->thread = ddekit_interrupt_attach(irq->irq, + irq->shared, + irq_thread_init, + irq_handler, + (void *)irq); + if (!irq->thread) { + ddekit_simple_free(irq); + return -EBUSY; + } + } + + /* does desciptor allow our new handler? */ + if ((!irq->shared || !shared) && irq->action) return -EBUSY; + + /* add handler */ + irq->count++; + action->next = irq->action; + irq->action = action; + + return irq->count; +} + + +/** + * Free previously claimed IRQ + * + * \return usage counter or negative error code + */ +static struct irqaction *release_irq(unsigned irq_num, void *dev_id) +{ + struct dde_irq *prev_irq, *irq; + + /* check if IRQ already used */ + for (prev_irq = 0, irq = used_irqs; irq; + prev_irq = irq, irq = irq->next) + if (irq->irq == irq_num) break; + + if (!irq) return 0; + + struct irqaction *prev_action, *action; + + for (prev_action = 0, action = irq->action; action; + prev_action = action, action = action->next) + if (action->dev_id == dev_id) break; + + if (!action) return 0; + + /* dequeue action from irq */ + if (prev_action) + prev_action->next = action->next; + else + irq->action = action->next; + + /* dequeue irq from used_irqs list and free structure, + if no more actions available */ + if (!irq->action) { + if (prev_irq) + prev_irq->next = irq->next; + else + used_irqs = irq->next; + + /* detach from interrupt */ + ddekit_interrupt_detach(irq->irq); + + ddekit_simple_free(irq); + } + + return action; +} + + +/*************** + ** Linux API ** + ***************/ + +/** + * Request interrupt + * + * \param irq interrupt number + * \param handler interrupt handler -> top half + * \param flags interrupt handling flags (SA_SHIRQ, ...) + * \param dev_name device name + * \param dev_id cookie passed back to handler + * + * \return 0 on success; error code otherwise + * + * \todo FIXME consider locking! + */ +int request_irq(unsigned int irq, irq_handler_t handler, + unsigned long flags, const char *dev_name, void *dev_id) +{ + if (!handler) return -EINVAL; + + /* facilitate Linux irqaction for this handler */ + struct irqaction *irq_action = ddekit_simple_malloc(sizeof(*irq_action)); + if (!irq_action) return -ENOMEM; + memset(irq_action, 0, sizeof(*irq_action)); + + irq_action->handler = handler; + irq_action->flags = flags; + irq_action->name = dev_name; + irq_action->dev_id = dev_id; + irq_action->irq = irq; + + /* attach to IRQ */ + int err = claim_irq(irq_action); + if (err < 0) return err; + + return 0; +} + +/** Release Interrupt + * \ingroup mod_irq + * + * \param irq interrupt number + * \param dev_id cookie passed back to handler + * + */ +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *irq_action = release_irq(irq, dev_id); + + if (irq_action) + ddekit_simple_free(irq_action); +} + +void disable_irq(unsigned int irq) +{ + ddekit_interrupt_disable(irq); +} + +void disable_irq_nosync(unsigned int irq) +{ + /* + * Note: + * In contrast to the _nosync semantics, DDEKit's + * disable definitely waits until a currently executed + * IRQ handler terminates. + */ + ddekit_interrupt_disable(irq); +} + +void enable_irq(unsigned int irq) +{ + ddekit_interrupt_enable(irq); +} diff --git a/libdde_linux26/lib/src/arch/l4/kmalloc.c b/libdde_linux26/lib/src/arch/l4/kmalloc.c new file mode 100644 index 00000000..065c13c7 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/kmalloc.c @@ -0,0 +1,199 @@ +/* + * \brief kmalloc() implementation + * \author Christian Helmuth + * \date 2007-01-24 + * + * In Linux 2.6 this resides in mm/slab.c. + * + * This implementation of kmalloc() stays with Linux's and uses kmem_caches for + * some power of two bytes. For larger allocations ddedkit_large_malloc() is + * used. This way, we optimize for speed and potentially waste memory + * resources. + */ + +/* Linux */ +#include +#include +#include +#include +#include +#include +#include + +/* DDEKit */ +#include +#include + +#include + +/* dummy */ +int forbid_dac; + +/* This stuff is needed by some drivers, e.g. for ethtool. + * XXX: This is a fake, implement it if you really need ethtool stuff. + */ +struct page* mem_map = NULL; +static bootmem_data_t contig_bootmem_data; +struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data }; + +int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + return 0; +} +EXPORT_SYMBOL(remap_pfn_range); + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_MALLOC 0 + +/******************** + ** Implementation ** + ********************/ + +/* + * These are the default caches for kmalloc. Custom caches can have other sizes. + */ +static struct cache_sizes malloc_sizes[] = { +#define CACHE(x) { .cs_size = (x) }, +#include + CACHE(ULONG_MAX) +#undef CACHE +}; + + +/* + * kmalloc() cache names + */ +static const char *malloc_names[] = { +#define CACHE(x) "size-" #x, +#include + NULL +#undef CACHE +}; + + +/** + * Find kmalloc() cache for size + */ +static struct kmem_cache *find_cache(size_t size) +{ + struct cache_sizes *sizes; + + for (sizes = malloc_sizes; size > sizes->cs_size; ++sizes) ; + + return sizes->cs_cachep; +} + + +/** + * Free previously allocated memory + * @objp: pointer returned by kmalloc. + * + * If @objp is NULL, no operation is performed. + * + * Don't free memory not originally allocated by kmalloc() + * or you will run into trouble. + */ +void kfree(const void *objp) +{ + if (!objp) return; + + /* find cache back-pointer */ + void **p = (void **)objp - 1; + + ddekit_log(DEBUG_MALLOC, "objp=%p cache=%p (%d)", + p, *p, *p ? kmem_cache_size(*p) : 0); + + if (*p) + /* free from cache */ + kmem_cache_free(*p, p); + else + /* no cache for this size - use ddekit free */ + ddekit_large_free(p); +} + + +/** + * Allocate memory + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * + * kmalloc is the normal method of allocating memory + * in the kernel. + */ +void *__kmalloc(size_t size, gfp_t flags) +{ + /* add space for back-pointer */ + size += sizeof(void *); + + /* find appropriate cache */ + struct kmem_cache *cache = find_cache(size); + + void **p; + if (cache) + /* allocate from cache */ + p = kmem_cache_alloc(cache, flags); + else + /* no cache for this size - use ddekit malloc */ + p = ddekit_large_malloc(size); + + ddekit_log(DEBUG_MALLOC, "size=%d, cache=%p (%d) => %p", + size, cache, cache ? kmem_cache_size(cache) : 0, p); + + /* return pointer to actual chunk */ + if (p) { + *p = cache; + p++; + } + return p; +} + + +size_t ksize(const void *p) +{ + struct kmem_cache *cache = (struct kmem_cache *)*((void**)p - 1); + if (cache) + return kmem_cache_size(cache); + return -1; +} + + +void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret = (void *)__get_free_pages(flag, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + + +void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + + +/******************** + ** Initialization ** + ********************/ + +/** + * dde_linux kmalloc initialization + */ +void l4dde26_kmalloc_init(void) +{ + struct cache_sizes *sizes = malloc_sizes; + const char **names = malloc_names; + + /* init malloc sizes array */ + for (; sizes->cs_size != ULONG_MAX; ++sizes, ++names) + sizes->cs_cachep = kmem_cache_create(*names, sizes->cs_size, 0, 0, 0); +} diff --git a/libdde_linux26/lib/src/arch/l4/kmem_cache.c b/libdde_linux26/lib/src/arch/l4/kmem_cache.c new file mode 100644 index 00000000..1465ac6c --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/kmem_cache.c @@ -0,0 +1,213 @@ +/* + * \brief Kmem_cache implementation + * \author Christian Helmuth + * \date 2007-01-22 + * + * In Linux 2.6 this resides in mm/slab.c. + * + * I'll disregard the following function currently... + * + * extern struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags); + * extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); + */ + +/* Linux */ +#include + +/* DDEKit */ +#include +#include + + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_SLAB 0 + +#if DEBUG_SLAB +# define DEBUG_SLAB_ALLOC 1 +#else +# define DEBUG_SLAB_ALLOC 0 +#endif + +/* + * Kmem cache structure + */ +struct kmem_cache +{ + const char *name; /**< cache name */ + unsigned size; /**< obj size */ + + struct ddekit_slab *ddekit_slab_cache; /**< backing DDEKit cache */ + ddekit_lock_t cache_lock; /**< lock */ + void (*ctor)(void *); /**< object constructor */ +}; + + +/** + * Return size of objects in cache + */ +unsigned int kmem_cache_size(struct kmem_cache *cache) +{ + return cache->size; +} + + +/** + * Return name of cache + */ +const char *kmem_cache_name(struct kmem_cache *cache) +{ + return cache->name; +} + + +/** + * kmem_cache_shrink - Shrink a cache. + * @cachep: The cache to shrink. + * + * Releases as many slabs as possible for a cache. + * To help debugging, a zero exit status indicates all slabs were released. + */ +int kmem_cache_shrink(struct kmem_cache *cache) +{ + /* noop */ + return 1; +} + + +/** + * kmem_cache_free - Deallocate an object + * @cachep: The cache the allocation was from. + * @objp: The previously allocated object. + * + * Free an object which was previously allocated from this + * cache. + */ +void kmem_cache_free(struct kmem_cache *cache, void *objp) +{ + ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" (%p)", cache->name, objp); + + ddekit_lock_lock(&cache->cache_lock); + ddekit_slab_free(cache->ddekit_slab_cache, objp); + ddekit_lock_unlock(&cache->cache_lock); +} + + +/** + * kmem_cache_alloc - Allocate an object + * @cachep: The cache to allocate from. + * @flags: See kmalloc(). + * + * Allocate an object from this cache. The flags are only relevant + * if the cache has no available objects. + */ +void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) +{ + void *ret; + + ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" flags=%x", cache->name, flags); + + ddekit_lock_lock(&cache->cache_lock); + ret = ddekit_slab_alloc(cache->ddekit_slab_cache); + ddekit_lock_unlock(&cache->cache_lock); + + // XXX: is it valid to run ctor AND memset to zero? + if (flags & __GFP_ZERO) + memset(ret, 0, cache->size); + else if (cache->ctor) + cache->ctor(ret); + + return ret; +} + + +/** + * kmem_cache_destroy - delete a cache + * @cachep: the cache to destroy + * + * Remove a struct kmem_cache object from the slab cache. + * Returns 0 on success. + * + * It is expected this function will be called by a module when it is + * unloaded. This will remove the cache completely, and avoid a duplicate + * cache being allocated each time a module is loaded and unloaded, if the + * module doesn't have persistent in-kernel storage across loads and unloads. + * + * The cache must be empty before calling this function. + * + * The caller must guarantee that noone will allocate memory from the cache + * during the kmem_cache_destroy(). + */ +void kmem_cache_destroy(struct kmem_cache *cache) +{ + ddekit_log(DEBUG_SLAB, "\"%s\"", cache->name); + + ddekit_slab_destroy(cache->ddekit_slab_cache); + ddekit_simple_free(cache); +} + + +/** + * kmem_cache_create - Create a cache. + * @name: A string which is used in /proc/slabinfo to identify this cache. + * @size: The size of objects to be created in this cache. + * @align: The required alignment for the objects. + * @flags: SLAB flags + * @ctor: A constructor for the objects. + * + * Returns a ptr to the cache on success, NULL on failure. + * Cannot be called within a int, but can be interrupted. + * The @ctor is run when new pages are allocated by the cache + * and the @dtor is run before the pages are handed back. + * + * @name must be valid until the cache is destroyed. This implies that + * the module calling this has to destroy the cache before getting unloaded. + * + * The flags are + * + * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) + * to catch references to uninitialised memory. + * + * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check + * for buffer overruns. + * + * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware + * cacheline. This can be beneficial if you're counting cycles as closely + * as davem. + */ +struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, + unsigned long flags, + void (*ctor)(void *)) +{ + ddekit_log(DEBUG_SLAB, "\"%s\" obj_size=%d", name, size); + + struct kmem_cache *cache; + + if (!name) { + printk("kmem_cache name reqeuired\n"); + return 0; + } + + cache = ddekit_simple_malloc(sizeof(*cache)); + if (!cache) { + printk("No memory for slab cache\n"); + return 0; + } + + /* Initialize a physically contiguous cache for kmem */ + if (!(cache->ddekit_slab_cache = ddekit_slab_init(size, 1))) { + printk("DDEKit slab init failed\n"); + ddekit_simple_free(cache); + return 0; + } + + cache->name = name; + cache->size = size; + cache->ctor = ctor; + + ddekit_lock_init_unlocked(&cache->cache_lock); + + return cache; +} diff --git a/libdde_linux26/lib/src/arch/l4/local.h b/libdde_linux26/lib/src/arch/l4/local.h new file mode 100644 index 00000000..35b3e449 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/local.h @@ -0,0 +1,99 @@ +#ifndef __DDE26_LOCAL_H +#define __DDE26_LOCAL_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DDE_DEBUG 1 +#define DDE_FERRET 0 + +/* Ferret Debugging stuff, note that this is the only point we are using + * L4 headers directly and only for debugging. */ +#if DDE_FERRET +#include +#include +#include +#include +#include +#include +extern ferret_list_local_t *ferret_ore_sensor; +#endif + +/*** + * Internal representation of a Linux kernel thread. This struct + * contains Linux' data as well as some additional data used by DDE. + */ +typedef struct dde26_thread_data +{ + /* NOTE: _threadinfo needs to be first in this struct! */ + struct thread_info _thread_info; ///< Linux thread info (see current()) + ddekit_thread_t *_ddekit_thread; ///< underlying DDEKit thread + ddekit_sem_t *_sleep_lock; ///< lock used for sleep_interruptible() + struct pid _vpid; ///< virtual PID +} dde26_thread_data; + +#define LX_THREAD(thread_data) ((thread_data)->_thread_info) +#define LX_TASK(thread_data) ((thread_data)->_thread_info.task) +#define DDEKIT_THREAD(thread_data) ((thread_data)->_ddekit_thread) +#define SLEEP_LOCK(thread_data) ((thread_data)->_sleep_lock) +#define VPID_P(thread_data) (&(thread_data)->_vpid) + +#if DDE_DEBUG +#define WARN_UNIMPL printk("unimplemented: %s\n", __FUNCTION__) +#define DEBUG_MSG(msg, ...) printk("%s: \033[36m"msg"\033[0m\n", __FUNCTION__, ##__VA_ARGS__) + +#define DECLARE_INITVAR(name) \ + static struct { \ + int _initialized; \ + char *name; \ + } init_##name = {0, #name,} + +#define INITIALIZE_INITVAR(name) init_##name._initialized = 1 + +#define CHECK_INITVAR(name) \ + if (init_##name._initialized == 0) { \ + printk("DDE26: \033[31;1mUsing uninitialized subsystem: "#name"\033[0m\n"); \ + BUG(); \ + } + +#else /* !DDE_DEBUG */ + +#define WARN_UNIMPL do {} while(0) +#define DEBUG_MSG(...) do {} while(0) +#define DECLARE_INITVAR(name) +#define CHECK_INITVAR(name) do {} while(0) +#define INITIALIZE_INITVAR(name) do {} while(0) + +#endif + +/* since _thread_info always comes first in the thread_data struct, + * we can derive the dde26_thread_data from a task struct by simply + * dereferencing its thread_info pointer + */ +static dde26_thread_data *lxtask_to_ddethread(struct task_struct *t) +{ + return (dde26_thread_data *)(task_thread_info(t)); +} + +extern struct thread_info init_thread; +extern struct task_struct init_task; + +#endif diff --git a/libdde_linux26/lib/src/arch/l4/mm-helper.c b/libdde_linux26/lib/src/arch/l4/mm-helper.c new file mode 100644 index 00000000..68c0213b --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/mm-helper.c @@ -0,0 +1,45 @@ +/* Linux */ +#include +#include +#include + +/* DDEKit */ +#include +#include +#include + +#include "local.h" + +int ioprio_best(unsigned short aprio, unsigned short bprio) +{ + WARN_UNIMPL; + return 0; +} + +void *__alloc_bootmem(unsigned long size, unsigned long align, + unsigned long goal) +{ + WARN_UNIMPL; + return 0; +} + +/* + * Stolen from linux-2.6.29/fs/libfs.c + */ +ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, + const void *from, size_t available) +{ + loff_t pos = *ppos; + if (pos < 0) + return -EINVAL; + if (pos > available) + return 0; + if (count > available - pos) + count = available - pos; + memcpy(to, from + pos, count); + *ppos = pos + count; + + return count; +} + +int capable(int f) { return 1; } diff --git a/libdde_linux26/lib/src/arch/l4/net.c b/libdde_linux26/lib/src/arch/l4/net.c new file mode 100644 index 00000000..d6637d96 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/net.c @@ -0,0 +1,36 @@ +/****************************************************************************** + * DDELinux networking utilities. * + * * + * Bjoern Doebel * + * * + * (c) 2005 - 2007 Technische Universitaet Dresden * + * This file is part of DROPS, which is distributed under the terms of the * + * GNU General Public License 2. Please see the COPYING file for details. * + ******************************************************************************/ + +#include + +#include +#include + +#include "local.h" + + +/* Callback function to be called if a network packet arrives and needs to + * be handled by netif_rx() or netif_receive_skb() + */ +linux_rx_callback l4dde26_rx_callback = NULL; + + +/* Register a netif_rx callback function. + * + * \return pointer to old callback function + */ +linux_rx_callback l4dde26_register_rx_callback(linux_rx_callback cb) +{ + linux_rx_callback old = l4dde26_rx_callback; + l4dde26_rx_callback = cb; + DEBUG_MSG("New rx callback @ %p.", cb); + + return old; +} diff --git a/libdde_linux26/lib/src/arch/l4/page_alloc.c b/libdde_linux26/lib/src/arch/l4/page_alloc.c new file mode 100644 index 00000000..0a2e3fdf --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/page_alloc.c @@ -0,0 +1,281 @@ +/* + * \brief Page allocation + * \author Christian Helmuth + * Bjoern Doebel + * \date 2007-01-22 + * + * In Linux 2.6 this resides in mm/page_alloc.c. + * + * This implementation is far from complete as it does not cover "struct page" + * emulation. In Linux, there's an array of structures for all pages. In + * particular, iteration works for this array like: + * + * struct page *p = alloc_pages(3); // p refers to first page of allocation + * ++p; // p refers to second page + * + * There may be more things to cover and we should have a deep look into the + * kernel parts we want to reuse. Candidates for problems may be file systems, + * storage (USB, IDE), and video (bttv). + */ + +/* Linux */ +#include +#include +#include +#include +#include + +/* DDEKit */ +#include +#include +#include + +#include "local.h" + +unsigned long max_low_pfn; +unsigned long min_low_pfn; +unsigned long max_pfn; + +/******************* + ** Configuration ** + *******************/ + +#define DEBUG_PAGE_ALLOC 0 + + +/* + * DDE page cache + * + * We need to store all pages somewhere (which in the Linux kernel is + * performed by the huge VM infrastructure. Purpose for us is: + * - make virt_to_phys() work + * - enable external clients to hand in memory (e.g., a dm_phys + * dataspace and make it accessible as Linux pages to the DDE) + */ + +#define DDE_PAGE_CACHE_SHIFT 10 +#define DDE_PAGE_CACHE_SIZE (1 << DDE_PAGE_CACHE_SHIFT) +#define DDE_PAGE_CACHE_MASK (DDE_PAGE_CACHE_SIZE - 1) + +typedef struct +{ + struct hlist_node list; + struct page *page; +} page_cache_entry; + +static struct hlist_head dde_page_cache[DDE_PAGE_CACHE_SIZE]; + +/** Hash function to map virtual addresses to page cache buckets. */ +#define VIRT_TO_PAGEHASH(a) ((((unsigned long)a) >> PAGE_SHIFT) & DDE_PAGE_CACHE_MASK) + + +void dde_page_cache_add(struct page *p) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(p->virtual); + + page_cache_entry *e = kmalloc(sizeof(page_cache_entry), GFP_KERNEL); + +#if DEBUG_PAGE_ALLOC + DEBUG_MSG("virt %p, hash: %x", p->virtual, hashval); +#endif + + e->page = p; + INIT_HLIST_NODE(&e->list); + + hlist_add_head(&e->list, &dde_page_cache[hashval]); +} + + +void dde_page_cache_remove(struct page *p) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(p->virtual); + struct hlist_node *hn = NULL; + struct hlist_head *h = &dde_page_cache[hashval]; + page_cache_entry *e = NULL; + struct hlist_node *v = NULL; + + hlist_for_each_entry(e, hn, h, list) { + if ((unsigned long)e->page->virtual == ((unsigned long)p->virtual & PAGE_MASK)) + v = hn; + break; + } + + if (v) { +#if DEBUG_PAGE_ALLOC + DEBUG_MSG("deleting node %p which contained page %p", v, p); +#endif + hlist_del(v); + } +} + + +struct page* dde_page_lookup(unsigned long va) +{ + unsigned int hashval = VIRT_TO_PAGEHASH(va); + + struct hlist_node *hn = NULL; + struct hlist_head *h = &dde_page_cache[hashval]; + page_cache_entry *e = NULL; + + hlist_for_each_entry(e, hn, h, list) { + if ((unsigned long)e->page->virtual == (va & PAGE_MASK)) + return e->page; + } + + return NULL; +} + + +struct page * __alloc_pages_internal(gfp_t gfp_mask, unsigned int order, + struct zonelist *zonelist, nodemask_t *nm) +{ + /* XXX: In fact, according to order, we should have one struct page + * for every page, not only for the first one. + */ + struct page *ret = kmalloc(sizeof(*ret), GFP_KERNEL); + + ret->virtual = (void *)__get_free_pages(gfp_mask, order); + dde_page_cache_add(ret); + + return ret; +} + + +unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) +{ + ddekit_log(DEBUG_PAGE_ALLOC, "gfp_mask=%x order=%d (%d bytes)", + gfp_mask, order, PAGE_SIZE << order); + + Assert(gfp_mask != GFP_DMA); + void *p = ddekit_large_malloc(PAGE_SIZE << order); + + return (unsigned long)p; +} + + +unsigned long get_zeroed_page(gfp_t gfp_mask) +{ + unsigned long p = __get_free_pages(gfp_mask, 0); + + if (p) memset((void *)p, 0, PAGE_SIZE); + + return (unsigned long)p; +} + + +void free_hot_page(struct page *page) +{ + WARN_UNIMPL; +} + +/* + * XXX: If alloc_pages() gets fixed to allocate a page struct per page, + * this needs to be adapted, too. + */ +void __free_pages(struct page *page, unsigned int order) +{ + free_pages((unsigned long)page->virtual, order); + dde_page_cache_remove(page); +} + +void __pagevec_free(struct pagevec *pvec) +{ + WARN_UNIMPL; +} + +int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, int len, int write, int force, + struct page **pages, struct vm_area_struct **vmas) +{ + WARN_UNIMPL; + return 0; +} + +/** + * ... + * + * XXX order may be larger than allocation at 'addr' - it may comprise several + * allocation via __get_free_pages()! + */ +void free_pages(unsigned long addr, unsigned int order) +{ + ddekit_log(DEBUG_PAGE_ALLOC, "addr=%p order=%d", (void *)addr, order); + + ddekit_large_free((void *)addr); +} + + +unsigned long __pa(volatile void *addr) +{ + return ddekit_pgtab_get_physaddr((void*)addr); +} + +void *__va(unsigned long addr) +{ + return (void*)ddekit_pgtab_get_virtaddr((ddekit_addr_t) addr); +} + + +int set_page_dirty_lock(struct page *page) +{ + WARN_UNIMPL; + return 0; +} + + +/* + * basically copied from linux/mm/page_alloc.c + */ +void *__init alloc_large_system_hash(const char *tablename, + unsigned long bucketsize, + unsigned long numentries, + int scale, + int flags, + unsigned int *_hash_shift, + unsigned int *_hash_mask, + unsigned long limit) +{ + void * table = NULL; + unsigned long log2qty; + unsigned long size; + + if (numentries == 0) + numentries = 1024; + + log2qty = ilog2(numentries); + size = bucketsize << log2qty; + + do { + unsigned long order; + for (order = 0; ((1UL << order) << PAGE_SHIFT) < size; order++); + table = (void*) __get_free_pages(GFP_ATOMIC, order); + } while (!table && size > PAGE_SIZE && --log2qty); + + if (!table) + panic("Failed to allocate %s hash table\n", tablename); + + printk("%s hash table entries: %d (order: %d, %lu bytes)\n", + tablename, + (1U << log2qty), + ilog2(size) - PAGE_SHIFT, + size); + + if (_hash_shift) + *_hash_shift = log2qty; + if (_hash_mask) + *_hash_mask = (1 << log2qty) - 1; + + return table; +} + + +static void __init dde_page_cache_init(void) +{ + printk("Initializing DDE page cache\n"); + int i=0; + + for (i; i < DDE_PAGE_CACHE_SIZE; ++i) + INIT_HLIST_HEAD(&dde_page_cache[i]); +} + +core_initcall(dde_page_cache_init); diff --git a/libdde_linux26/lib/src/arch/l4/param.c b/libdde_linux26/lib/src/arch/l4/param.c new file mode 100644 index 00000000..5bd83f32 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/param.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Lazy bastard, eh? */ +#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ + int param_set_##name(const char *val, struct kernel_param *kp) \ + { \ + return 0; \ + } \ + int param_get_##name(char *buffer, struct kernel_param *kp) \ + { \ + return 0;\ + } + +STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol); +STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol); +STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); +STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); + +int printk_ratelimit(void) +{ + return 0; +} diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c new file mode 100644 index 00000000..2a0391f2 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -0,0 +1,189 @@ +#include "local.h" + +#include +#include +#include +#include + +/* will include $(CONTRIB)/drivers/pci/pci.h */ +#include "pci.h" + +DECLARE_INITVAR(dde26_pci); + +/** PCI device descriptor */ +typedef struct l4dde_pci_dev { + struct list_head next; /**< chain info */ + struct ddekit_pci_dev *ddekit_dev; /**< corresponding DDEKit descriptor */ + struct pci_dev *linux_dev; /**< Linux descriptor */ +} l4dde_pci_dev_t; + + +/******************************************************************************************* + ** PCI data ** + *******************************************************************************************/ +/** List of Linux-DDEKit PCIDev mappings */ +static LIST_HEAD(pcidev_mappings); + +/** PCI bus */ +static struct pci_bus *pci_bus = NULL; + +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); + +/** PCI operations for our virtual PCI bus */ +static struct pci_ops dde_pcibus_ops = { + .read = l4dde26_pci_read, + .write = l4dde26_pci_write, +}; + + +/******************************************************************************************* + ** Read/write PCI config space. This is simply mapped to the DDEKit functions. ** + *******************************************************************************************/ +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) +{ + return ddekit_pci_read(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + return ddekit_pci_write(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +int pci_irq_enable(struct pci_dev *dev) +{ + int irq = dev->irq; + int pin = 0; + int ret; + + DEBUG_MSG("dev %p", dev); + if (!dev) + return -EINVAL; + + pin = (int)dev->pin; + DEBUG_MSG("irq %d, pin %d", dev->irq, dev->pin); + if (!pin) { + dev_warn(&dev->dev, + "No interrupt pin configured for device %s\n", + pci_name(dev)); + return 0; + } + pin--; + + ret = ddekit_pci_irq_enable(dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), pin, &irq); + if (ret) { + dev_warn(&dev->dev, "Interrupt enable failed for device %s (%d)\n", + pci_name(dev), ret); + return -1; + } + + dev_info(&dev->dev, "PCI INT %c -> GSI %d -> IRQ %d\n", + 'A' + pin, irq, dev->irq); + + dev->irq = irq; + return 0; +} + +int __pci_enable_device(struct pci_dev *dev) +{ + WARN_UNIMPL; + return 0; +} + + +/** + * pci_enable_device - Initialize device before it's used by a driver. + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O and memory. Wake up the device if it was suspended. + * Beware, this function can fail. + * + * \param dev PCI device to be initialized + * + */ +int +pci_enable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); +// WARN_UNIMPL; + return pci_irq_enable(dev); +} + + +/** + * pci_disable_device - Disable PCI device after use + * + * Signal to the system that the PCI device is not in use by the system + * anymore. This only involves disabling PCI bus-mastering, if active. + * + * \param dev PCI device to be disabled + */ +void pci_disable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); + WARN_UNIMPL; +} + + +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) +{ + //WARN_UNIMPL; +} + +void pci_set_master(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); + WARN_UNIMPL; +} + + +int pci_create_sysfs_dev_files(struct pci_dev *pdev) +{ + return 0; +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +void +pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + WARN_UNIMPL; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ +#if 0 + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return pcibios_enable_irq(dev); +#endif + return 0; +} + +/******************************************************************************************* + ** Initialization function ** + *******************************************************************************************/ + +/** Initialize DDELinux PCI subsystem. + */ +void __init l4dde26_init_pci(void) +{ + ddekit_pci_init(); + + pci_bus = pci_create_bus(NULL, 0, &dde_pcibus_ops, NULL); + Assert(pci_bus); + + pci_do_scan_bus(pci_bus); + + INITIALIZE_INITVAR(dde26_pci); +} + +arch_initcall(l4dde26_init_pci); diff --git a/libdde_linux26/lib/src/arch/l4/power.c b/libdde_linux26/lib/src/arch/l4/power.c new file mode 100644 index 00000000..e36487bd --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/power.c @@ -0,0 +1,23 @@ +/* Dummy functions for power management. */ + +#include "local.h" +#include + +int device_pm_add(struct device * dev) +{ + WARN_UNIMPL; + return 0; +} + + +void device_pm_remove(struct device * dev) +{ + WARN_UNIMPL; +} + +int pm_qos_add_requirement(int qos, char *name, s32 value) { return 0; } +int pm_qos_update_requirement(int qos, char *name, s32 new_value) { return 0; } +void pm_qos_remove_requirement(int qos, char *name) { } +int pm_qos_requirement(int qos) { return 0; } +int pm_qos_add_notifier(int qos, struct notifier_block *notifier) { return 0; } +int pm_qos_remove_notifier(int qos, struct notifier_block *notifier) { return 0; } diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c new file mode 100644 index 00000000..5fe43b32 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -0,0 +1,347 @@ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "local.h" + +/***************************************************************************** + ** Current() implementation ** + *****************************************************************************/ +struct thread_info *current_thread_info(void) +{ + dde26_thread_data *cur = (dde26_thread_data *)ddekit_thread_get_my_data(); + return &LX_THREAD(cur); +} + +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +/***************************************************************************** + ** PID-related stuff ** + ** ** + ** Linux manages lists of PIDs that are handed out to processes so that at ** + ** a later point it is able to determine which task_struct belongs to a ** + ** certain PID. We implement this with a single list holding the mappings ** + ** for all our threads. ** + *****************************************************************************/ + +LIST_HEAD(_pid_task_list); +ddekit_lock_t _pid_task_list_lock; + +/** PID to task_struct mapping */ +struct pid2task +{ + struct list_head list; /**< list data */ + struct pid *pid; /**< PID */ + struct task_struct *ts; /**< task struct */ +}; + +struct pid init_struct_pid = INIT_STRUCT_PID; + +void put_pid(struct pid *pid) +{ + if (pid) + atomic_dec(&pid->count); + // no freeing here, our struct pid's are always allocated as + // part of the dde26_thread_data +} + +/** Attach PID to a certain task struct. */ +void attach_pid(struct task_struct *task, enum pid_type type + __attribute__((unused)), struct pid *pid) +{ + /* Initialize a new pid2task mapping */ + struct pid2task *pt = kmalloc(sizeof(struct pid2task), GFP_KERNEL); + pt->pid = get_pid(pid); + pt->ts = task; + + /* add to list */ + ddekit_lock_lock(&_pid_task_list_lock); + list_add(&pt->list, &_pid_task_list); + ddekit_lock_unlock(&_pid_task_list_lock); +} + +/** Detach PID from a task struct. */ +void detach_pid(struct task_struct *task, enum pid_type type __attribute__((unused))) +{ + struct list_head *p, *n, *h; + + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + /* search for mapping with given task struct and free it if necessary */ + list_for_each_safe(p, n, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pt->ts == task) { + put_pid(pt->pid); + list_del(p); + kfree(pt); + break; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); +} + +struct task_struct *find_task_by_pid_type(int type, int nr) +{ + struct list_head *h, *p; + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + list_for_each(p, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pid_nr(pt->pid) == nr) { + ddekit_lock_unlock(&_pid_task_list_lock); + return pt->ts; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); + + return NULL; +} + + +struct task_struct *find_task_by_pid_ns(int nr, struct pid_namespace *ns) +{ + /* we don't implement PID name spaces */ + return find_task_by_pid_type(0, nr); +} + +struct task_struct *find_task_by_pid(int nr) +{ + return find_task_by_pid_type(0, nr); +} + +/***************************************************************************** + ** kernel_thread() implementation ** + *****************************************************************************/ +/* Struct containing thread data for a newly created kthread. */ +struct __kthread_data +{ + int (*fn)(void *); + void *arg; + ddekit_lock_t lock; + dde26_thread_data *kthread; +}; + +/** Counter for running kthreads. It is used to create unique names + * for kthreads. + */ +static atomic_t kthread_count = ATOMIC_INIT(0); + +/** Entry point for new kernel threads. Make this thread a DDE26 + * worker and then execute the real thread fn. + */ +static void __kthread_helper(void *arg) +{ + struct __kthread_data *k = (struct __kthread_data *)arg; + + /* + * Make a copy of the fn and arg pointers, as the kthread struct is + * deleted by our parent after notifying it and this may happen before we + * get to execute the function. + */ + int (*_fn)(void*) = k->fn; + void *_arg = k->arg; + + l4dde26_process_add_worker(); + + /* + * Handshake with creator - we store our thread data in the + * kthread struct and then unlock the lock to notify our + * creator about completing setup + */ + k->kthread = (dde26_thread_data *)ddekit_thread_get_my_data(); + ddekit_lock_unlock(&k->lock); + + do_exit(_fn(_arg)); +} + +/** Our implementation of Linux' kernel_thread() function. Setup a new + * thread running our __kthread_helper() function. + */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + ddekit_thread_t *t; + char name[20]; + struct __kthread_data *kt = vmalloc(sizeof(struct __kthread_data)); + ddekit_lock_t lock; + + /* Initialize (and grab) handshake lock */ + ddekit_lock_init(&lock); + ddekit_lock_lock(&lock); + + int threadnum = atomic_inc_return(&kthread_count); + kt->fn = fn; + kt->arg = arg; + kt->lock = lock; // Copy lock ptr, note that kt is freed by the + // new thread, so we MUST NOT use kt->lock after + // this point! + + snprintf(name, 20, ".kthread%x", threadnum); + t = ddekit_thread_create(__kthread_helper, + (void *)kt, name); + Assert(t); + + ddekit_lock_lock(&lock); + ddekit_lock_deinit(&lock); + + return pid_nr(VPID_P(kt->kthread)); +} + +/** Our implementation of exit(). For DDE purposes this only relates + * to kernel threads. + */ +void do_exit(long code) +{ + ddekit_thread_t *t = DDEKIT_THREAD(lxtask_to_ddethread(current)); +// printk("Thread %s exits with code %x\n", ddekit_thread_get_name(t), code); + + /* do some cleanup */ + detach_pid(current, 0); + + /* goodbye, cruel world... */ + ddekit_thread_exit(); +} + +/***************************************************************************** + ** Misc functions ** + *****************************************************************************/ + +void dump_stack(void) +{ +} + + +char *get_task_comm(char *buf, struct task_struct *tsk) +{ + char *ret; + /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); + ret = strncpy(buf, tsk->comm, sizeof(tsk->comm)); + task_unlock(tsk); + return ret; +} + + +void set_task_comm(struct task_struct *tsk, char *buf) +{ + task_lock(tsk); + strlcpy(tsk->comm, buf, sizeof(tsk->comm)); + task_unlock(tsk); +} + + +/***************************************************************************** + ** DDEKit gluecode, init functions ** + *****************************************************************************/ +/* Initialize a dde26 thread. + * + * - Allocate thread data, as well as a Linux task struct, + * - Fill in default values for thread_info, and task, + * - Adapt task struct's thread_info backreference + * - Initialize the DDE sleep lock + */ +static dde26_thread_data *init_dde26_thread(void) +{ + /* + * Virtual PID counter + */ + static atomic_t pid_counter = ATOMIC_INIT(0); + dde26_thread_data *t = vmalloc(sizeof(dde26_thread_data)); + Assert(t); + + memcpy(&t->_vpid, &init_struct_pid, sizeof(struct pid)); + t->_vpid.numbers[0].nr = atomic_inc_return(&pid_counter); + + memcpy(&LX_THREAD(t), &init_thread, sizeof(struct thread_info)); + + LX_TASK(t) = vmalloc(sizeof(struct task_struct)); + Assert(LX_TASK(t)); + + memcpy(LX_TASK(t), &init_task, sizeof(struct task_struct)); + + /* nice: Linux backreferences a task`s thread_info from the + * task struct (which in turn can be found using the + * thread_info...) */ + LX_TASK(t)->stack = &LX_THREAD(t); + + /* initialize this thread's sleep lock */ + SLEEP_LOCK(t) = ddekit_sem_init(0); + + return t; +} + +/* Process setup for worker threads */ +int l4dde26_process_add_worker(void) +{ + dde26_thread_data *cur = init_dde26_thread(); + + /* If this function is called for a kernel_thread, the thread already has + * been set up and we just need to store a reference to the ddekit struct. + * However, this function may also be called directly to turn an L4 thread + * into a DDE thread. Then, we need to initialize here. */ + cur->_ddekit_thread = ddekit_thread_myself(); + if (cur->_ddekit_thread == NULL) + cur->_ddekit_thread = ddekit_thread_setup_myself(".dde26_thread"); + Assert(cur->_ddekit_thread); + + ddekit_thread_set_my_data(cur); + + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + /* Linux' default is to have this set to 1 initially and let the + * scheduler set this to 0 later on. + */ + current_thread_info()->preempt_count = 0; + + return 0; +} + + +/** + * Add an already existing DDEKit thread to the set of threads known to the + * Linux environment. This is used for the timer thread, which is actually a + * DDEKit thread, but Linux code shall see it as a Linux thread as well. + */ +int l4dde26_process_from_ddekit(ddekit_thread_t *t) +{ + Assert(t); + + dde26_thread_data *cur = init_dde26_thread(); + cur->_ddekit_thread = t; + ddekit_thread_set_data(t, cur); + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + return 0; +} + +/** Function to initialize the first DDE process. + */ +int __init l4dde26_process_init(void) +{ + ddekit_lock_init_unlocked(&_pid_task_list_lock); + + int kthreadd_pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); + kthreadd_task = find_task_by_pid(kthreadd_pid); + + l4dde26_process_add_worker(); + + return 0; +} + +DEFINE_PER_CPU(int, cpu_number); + +//dde_process_initcall(l4dde26_process_init); diff --git a/libdde_linux26/lib/src/arch/l4/res.c b/libdde_linux26/lib/src/arch/l4/res.c new file mode 100644 index 00000000..fbd2d09b --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/res.c @@ -0,0 +1,180 @@ +#include "local.h" + +#include + +/** Request an IO port region. + * + * \param start start port + * \param n number of ports + * \param name name of allocator (unused) + * + * \return NULL error + * \return !=NULL success + * + * \bug Since no one in Linux uses this function's return value, + * we do not allocate and fill a resource struct. + */ +static struct resource *l4dde26_request_region(resource_size_t start, + resource_size_t n, + const char *name) +{ + int err = ddekit_request_io(start, n); + + if (err) + return NULL; + + return (struct resource *)1; +} + + +/** List of memory regions that have been requested. This is used to + * perform ioremap() and iounmap() + */ +static LIST_HEAD(dde_mem_regions); + +/** va->pa mapping used to store memory regions */ +struct dde_mem_region { + ddekit_addr_t pa; + ddekit_addr_t va; + unsigned int size; + struct list_head list; +}; + +void __iomem * ioremap(unsigned long phys_addr, unsigned long size); + +/** Request an IO memory region. + * + * \param start start address + * \param n size of memory area + * \param name name of allocator (unused) + * + * \return NULL error + * \return !=NULL success + * + * \bug Since no one in Linux uses this function's return value, + * we do not allocate and fill a resource struct. + */ +static struct resource *l4dde26_request_mem_region(resource_size_t start, + resource_size_t n, + const char *name) +{ + ddekit_addr_t va = 0; + struct dde_mem_region *mreg; + + // do not a resource request twice + if (ioremap(start, n)) + return (struct resource *)1; + + int i = ddekit_request_mem(start, n, &va); + + if (i) { + ddekit_printf("request_mem_region() failed (start %lx, size %x)", start, n); + return NULL; + } + + mreg = kmalloc(sizeof(struct dde_mem_region), GFP_KERNEL); + Assert(mreg); + + mreg->pa = start; + mreg->va = va; + mreg->size = n; + list_add(&mreg->list, &dde_mem_regions); + +#if 0 + ddekit_pgtab_set_region_with_size((void *)va, start, n, PTE_TYPE_OTHER); +#endif + + return (struct resource *)1; +} + + +struct resource * __request_region(struct resource *parent, + resource_size_t start, + resource_size_t n, + const char *name, int flags) +{ + Assert(parent); + Assert(parent->flags & IORESOURCE_IO || parent->flags & IORESOURCE_MEM); + + switch (parent->flags) + { + case IORESOURCE_IO: + return l4dde26_request_region(start, n, name); + case IORESOURCE_MEM: + return l4dde26_request_mem_region(start, n, name); + } + + return NULL; +} + + +/** Release IO port region. + */ +static void l4dde26_release_region(resource_size_t start, resource_size_t n) +{ + /* FIXME: we need a list of "struct resource"s that have been + * allocated by request_region() and then need to + * free this stuff here! */ + ddekit_release_io(start, n); +} + + +/** Release IO memory region. + */ +static void l4dde26_release_mem_region(resource_size_t start, resource_size_t n) +{ + ddekit_release_mem(start, n); + ddekit_pgtab_clear_region((void *)start, PTE_TYPE_OTHER); +} + + +int __check_region(struct resource *root, resource_size_t s, resource_size_t n) +{ + WARN_UNIMPL; + return -1; +} + +void __release_region(struct resource *root, resource_size_t start, + resource_size_t n) +{ + switch (root->flags) + { + case IORESOURCE_IO: + return l4dde26_release_region(start, n); + case IORESOURCE_MEM: + return l4dde26_release_mem_region(start, n); + } +} + + +/** Map physical I/O region into virtual address space. + * + * For our sake, this only returns the virtual address belonging to + * the physical region, since we don't manage page tables ourselves. + */ +void __iomem * ioremap(unsigned long phys_addr, unsigned long size) +{ + struct list_head *pos, *head; + head = &dde_mem_regions; + + list_for_each(pos, head) { + struct dde_mem_region *mreg = list_entry(pos, struct dde_mem_region, + list); + if (mreg->pa <= phys_addr && mreg->pa + mreg->size >= phys_addr + size) + return (void *)(mreg->va + (phys_addr - mreg->pa)); + } + + return NULL; +} + + +void __iomem * ioremap_nocache(unsigned long offset, unsigned long size) +{ + return ioremap(offset, size); +} + + +void iounmap(volatile void __iomem *addr) +{ + WARN_UNIMPL; +} diff --git a/libdde_linux26/lib/src/arch/l4/sched.c b/libdde_linux26/lib/src/arch/l4/sched.c new file mode 100644 index 00000000..b38520c6 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/sched.c @@ -0,0 +1,155 @@ +#include "local.h" + +#include + +DEFINE_RWLOCK(tasklist_lock); + +asmlinkage void preempt_schedule(void) +{ + WARN_UNIMPL; +} + + +/* Our version of scheduler invocation. + * + * Scheduling is performed by Fiasco, so we don't care about it as long as + * a thread is running. If a task becomes TASK_INTERRUPTIBLE or + * TASK_UNINTERRUPTIBLE, we make sure that the task does not become + * scheduled by locking the task's sleep lock. + */ +asmlinkage void schedule(void) +{ + dde26_thread_data *t = lxtask_to_ddethread(current); + + switch (current->state) { + case TASK_RUNNING: + ddekit_thread_schedule(); + break; + case TASK_INTERRUPTIBLE: + case TASK_UNINTERRUPTIBLE: + ddekit_sem_down(SLEEP_LOCK(t)); + break; + default: + panic("current->state = %d --- unknown state\n", current->state); + } +} + + +/** yield the current processor to other threads. + * + * this is a shortcut for kernel-space yielding - it marks the + * thread runnable and calls sys_sched_yield(). + */ +void __sched yield(void) +{ + set_current_state(TASK_RUNNING); + ddekit_yield(); +} + + +/*** + * try_to_wake_up - wake up a thread + * @p: the to-be-woken-up thread + * @state: the mask of task states that can be woken + * @sync: do a synchronous wakeup? + */ +int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) +{ + Assert(p); + dde26_thread_data *t = lxtask_to_ddethread(p); + + Assert(t); + Assert(SLEEP_LOCK(t)); + + p->state = TASK_RUNNING; + ddekit_sem_up(SLEEP_LOCK(t)); + + return 0; +} + + +static void process_timeout(unsigned long data) +{ + wake_up_process((struct task_struct *)data); +} + + +signed long __sched schedule_timeout(signed long timeout) +{ + struct timer_list timer; + unsigned long expire = timeout + jiffies; + + setup_timer(&timer, process_timeout, (unsigned long)current); + timer.expires = expire; + + switch(timeout) + { + /* + * Hah! + * + * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule + * the CPU away without a bound on the timeout. In this case the return + * value will be %MAX_SCHEDULE_TIMEOUT. + */ + case MAX_SCHEDULE_TIMEOUT: + schedule(); + break; + default: + add_timer(&timer); + schedule(); + del_timer(&timer); + break; + } + + timeout = expire - jiffies; + + return timeout < 0 ? 0 : timeout; +} + + +signed long __sched schedule_timeout_interruptible(signed long timeout) +{ + __set_current_state(TASK_INTERRUPTIBLE); + return schedule_timeout(timeout); +} + + +signed long __sched schedule_timeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_timeout(timeout); +} + +/** Tasks may be forced to run only on a certain no. of CPUs. Since + * we only emulate a SMP-environment for the sake of having multiple + * threads, we do not need to implement this. + */ +int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) +{ + return 0; +} + +void set_user_nice(struct task_struct *p, long nice) +{ + //WARN_UNIMPL; +} + +void __sched io_schedule(void) +{ + WARN_UNIMPL; +} + +long __sched io_schedule_timeout(long timeout) +{ + WARN_UNIMPL; + return -1; +} + +extern int sched_setscheduler_nocheck(struct task_struct *t, int flags, + struct sched_param *p) +{ + WARN_UNIMPL; + return -1; +} + +void ignore_signals(struct task_struct *t) { } diff --git a/libdde_linux26/lib/src/arch/l4/signal.c b/libdde_linux26/lib/src/arch/l4/signal.c new file mode 100644 index 00000000..bd0bc0a7 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/signal.c @@ -0,0 +1,24 @@ +#include "local.h" + +/****************************************************************************** + ** Dummy signal implementation. ** + ** DDE does not provide its own signal implementation. To make it compile, ** + ** we provide dummy versions of signalling functions here. If later on ** + ** someone *REALLY* wants to use signals in the DDE context, he might ** + ** erase this file and use something like the L4 signalling library for ** + ** such purposes. ** +*******************************************************************************/ + +int sigprocmask(int how, sigset_t *set, sigset_t *oldset) +{ + return 0; +} + +void flush_signals(struct task_struct *t) +{ +} + +int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) +{ + return 0; +} diff --git a/libdde_linux26/lib/src/arch/l4/smp.c b/libdde_linux26/lib/src/arch/l4/smp.c new file mode 100644 index 00000000..1ebf08c2 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/smp.c @@ -0,0 +1,37 @@ +#include + +#include "local.h" + +static struct cpumask _possible = CPU_MASK_ALL; +static struct cpumask _online = CPU_MASK_CPU0; +static struct cpumask _present = CPU_MASK_CPU0; +static struct cpumask _active = CPU_MASK_CPU0; + +const struct cpumask *const cpu_possible_mask = &_possible; +const struct cpumask *const cpu_online_mask = &_online; +const struct cpumask *const cpu_present_mask = &_present; +const struct cpumask *const cpu_active_mask = &_active; + +cpumask_t cpu_mask_all = CPU_MASK_ALL; +int nr_cpu_ids = NR_CPUS; +const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); + +/* cpu_bit_bitmap[0] is empty - so we can back into it */ +#define MASK_DECLARE_1(x) [x+1][0] = 1UL << (x) +#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1) +#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2) +#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4) + +const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = { + MASK_DECLARE_8(0), MASK_DECLARE_8(8), + MASK_DECLARE_8(16), MASK_DECLARE_8(24), +#if BITS_PER_LONG > 32 + MASK_DECLARE_8(32), MASK_DECLARE_8(40), + MASK_DECLARE_8(48), MASK_DECLARE_8(56), +#endif +}; + +void __smp_call_function_single(int cpuid, struct call_single_data *data) +{ + data->func(data->info); +} diff --git a/libdde_linux26/lib/src/arch/l4/softirq.c b/libdde_linux26/lib/src/arch/l4/softirq.c new file mode 100644 index 00000000..21b36d17 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/softirq.c @@ -0,0 +1,267 @@ +#include "local.h" + +#include + +/* There are at most 32 softirqs in Linux, but only 6 are really used. */ +#define NUM_SOFTIRQS 6 + +DECLARE_INITVAR(dde26_softirq); + +/* softirq threads and their wakeup semaphores */ +ddekit_thread_t *dde_softirq_thread; +ddekit_sem_t *dde_softirq_sem; + +/* struct tasklet_head is not defined in a header in Linux 2.6 */ +struct tasklet_head +{ + struct tasklet_struct *list; + ddekit_lock_t lock; /* list lock */ +}; + +/* What to do if a softirq occurs. */ +static struct softirq_action softirq_vec[32]; + +/* tasklet queues for each softirq thread */ +struct tasklet_head tasklet_vec; +struct tasklet_head tasklet_hi_vec; + +void open_softirq(int nr, void (*action)(struct softirq_action*)) +{ + softirq_vec[nr].action = action; +} + +static void raise_softirq_irqoff_cpu(unsigned int nr, unsigned int cpu) +{ + CHECK_INITVAR(dde26_softirq); + + /* mark softirq scheduled */ + __raise_softirq_irqoff(nr); + /* wake softirq thread */ + ddekit_sem_up(dde_softirq_sem); +} + +void raise_softirq_irqoff(unsigned int nr) +{ + raise_softirq_irqoff_cpu(nr, 0); +} + +void raise_softirq(unsigned int nr) +{ + unsigned long flags; + + local_irq_save(flags); + raise_softirq_irqoff(nr); + local_irq_restore(flags); +} + +/** + * Initialize tasklet. + */ +void tasklet_init(struct tasklet_struct *t, + void (*func)(unsigned long), unsigned long data) +{ + t->next = NULL; + t->state = 0; + atomic_set(&t->count, 0); + t->func = func; + t->data = data; +} + +/* enqueue tasklet */ +static void __tasklet_enqueue(struct tasklet_struct *t, + struct tasklet_head *listhead) +{ + ddekit_lock_lock(&listhead->lock); + t->next = listhead->list; + listhead->list = t; + ddekit_lock_unlock(&listhead->lock); +} + +void __tasklet_schedule(struct tasklet_struct *t) +{ + unsigned long flags; + + CHECK_INITVAR(dde26_softirq); + + local_irq_save(flags); + + __tasklet_enqueue(t, &tasklet_vec); + /* raise softirq */ + raise_softirq_irqoff_cpu(TASKLET_SOFTIRQ, 0); + + local_irq_restore(flags); +} + +void __tasklet_hi_schedule(struct tasklet_struct *t) +{ + unsigned long flags; + + CHECK_INITVAR(dde26_softirq); + + local_irq_save(flags); + __tasklet_enqueue(t, &tasklet_hi_vec); + raise_softirq_irqoff_cpu(HI_SOFTIRQ, 0); + local_irq_restore(flags); +} + +/* Execute tasklets */ +static void tasklet_action(struct softirq_action *a) +{ + struct tasklet_struct *list; + + ddekit_lock_lock(&tasklet_vec.lock); + list = tasklet_vec.list; + tasklet_vec.list = NULL; + ddekit_lock_unlock(&tasklet_vec.lock); + + while (list) { + struct tasklet_struct *t = list; + + list = list->next; + + if (tasklet_trylock(t)) { + if (!atomic_read(&t->count)) { + if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + BUG(); + t->func(t->data); + tasklet_unlock(t); + continue; + } + tasklet_unlock(t); + } + + ddekit_lock_lock(&tasklet_vec.lock); + t->next = tasklet_vec.list; + tasklet_vec.list = t; + raise_softirq_irqoff_cpu(TASKLET_SOFTIRQ, 0); + ddekit_lock_unlock(&tasklet_vec.lock); + } +} + + +static void tasklet_hi_action(struct softirq_action *a) +{ + struct tasklet_struct *list; + + ddekit_lock_lock(&tasklet_hi_vec.lock); + list = tasklet_hi_vec.list; + tasklet_hi_vec.list = NULL; + ddekit_lock_unlock(&tasklet_hi_vec.lock); + + while (list) { + struct tasklet_struct *t = list; + + list = list->next; + + if (tasklet_trylock(t)) { + if (!atomic_read(&t->count)) { + if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) + BUG(); + t->func(t->data); + tasklet_unlock(t); + continue; + } + tasklet_unlock(t); + } + + ddekit_lock_lock(&tasklet_hi_vec.lock); + t->next = tasklet_hi_vec.list; + tasklet_hi_vec.list = t; + raise_softirq_irqoff_cpu(HI_SOFTIRQ, 0); + ddekit_lock_unlock(&tasklet_hi_vec.lock); + } +} + + +#define MAX_SOFTIRQ_RETRIES 10 + +/** Run softirq handlers + */ +void __do_softirq(void) +{ + int retries = MAX_SOFTIRQ_RETRIES; + do { + struct softirq_action *h = softirq_vec; + unsigned long pending = local_softirq_pending(); + + /* reset softirq count */ + set_softirq_pending(0); + + /* While we have a softirq pending... */ + while (pending) { + /* need to execute current softirq? */ + if (pending & 1) + h->action(h); + /* try next softirq */ + h++; + /* remove pending flag for last softirq */ + pending >>= 1; + } + + /* Somebody might have scheduled another softirq in between + * (e.g., an IRQ thread or another tasklet). */ + } while (local_softirq_pending() && --retries); + +} + + +void do_softirq(void) +{ + unsigned long flags; + + local_irq_save(flags); + if (local_softirq_pending()) + __do_softirq(); + local_irq_restore(flags); +} + +/** Softirq thread function. + * + * Once started, a softirq thread waits for tasklets to be scheduled + * and executes them. + * + * \param arg # of this softirq thread so that it grabs the correct lock + * if multiple softirq threads are running. + */ +void l4dde26_softirq_thread(void *arg) +{ + printk("Softirq daemon starting\n"); + l4dde26_process_add_worker(); + + /* This thread will always be in a softirq, so set the + * corresponding flag right now. + */ + preempt_count() |= SOFTIRQ_MASK; + + while(1) { + ddekit_sem_down(dde_softirq_sem); + do_softirq(); + } +} + +/** Initialize softirq subsystem. + * + * Start NUM_SOFTIRQ_THREADS threads executing the \ref l4dde26_softirq_thread + * function. + */ +void l4dde26_softirq_init(void) +{ + char name[20]; + + dde_softirq_sem = ddekit_sem_init(0); + + set_softirq_pending(0); + + ddekit_lock_init_unlocked(&tasklet_vec.lock); + ddekit_lock_init_unlocked(&tasklet_hi_vec.lock); + + snprintf(name, 20, ".softirqd"); + dde_softirq_thread = ddekit_thread_create( + l4dde26_softirq_thread, + NULL, name); + + open_softirq(TASKLET_SOFTIRQ, tasklet_action); + open_softirq(HI_SOFTIRQ, tasklet_hi_action); + + INITIALIZE_INITVAR(dde26_softirq); +} 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); +} diff --git a/libdde_linux26/lib/src/arch/l4/vmalloc.c b/libdde_linux26/lib/src/arch/l4/vmalloc.c new file mode 100644 index 00000000..134b80c3 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/vmalloc.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * Bjoern Doebel * + * * + * (c) 2005 - 2007 Technische Universitaet Dresden * + * This file is part of DROPS, which is distributed under the terms of the * + * GNU General Public License 2. Please see the COPYING file for details. * + ******************************************************************************/ + +/* + * \brief vmalloc implementation + * \author Bjoern Doebel + * \date 2007-07-30 + */ + +/* Linux */ +#include + +/* DDEKit */ +#include +#include + +void *vmalloc(unsigned long size) +{ + return ddekit_simple_malloc(size); +} + +void vfree(const void *addr) +{ + ddekit_simple_free((void*)addr); +} diff --git a/libdde_linux26/lib/src/arch/l4/vmstat.c b/libdde_linux26/lib/src/arch/l4/vmstat.c new file mode 100644 index 00000000..2e87389e --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/vmstat.c @@ -0,0 +1,34 @@ +#include "local.h" + +#include + +atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; + + +void dec_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + + +void inc_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + + +void __inc_zone_page_state(struct page *page, enum zone_stat_item item) +{ + WARN_UNIMPL; +} + +void __get_zone_counts(unsigned long *active, unsigned long *inactive, + unsigned long *free, struct pglist_data *pgdat) +{ + WARN_UNIMPL; +} + +void __dec_zone_state(struct zone *zone, enum zone_stat_item item) +{ + WARN_UNIMPL; +} diff --git a/libdde_linux26/lib/src/arch/x86/.svn/all-wcprops b/libdde_linux26/lib/src/arch/x86/.svn/all-wcprops new file mode 100644 index 00000000..2db9a887 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 67 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/x86 +END diff --git a/libdde_linux26/lib/src/arch/x86/.svn/entries b/libdde_linux26/lib/src/arch/x86/.svn/entries new file mode 100644 index 00000000..cdbe1e1d --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/.svn/entries @@ -0,0 +1,31 @@ +9 + +dir +465 +http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/lib/src/arch/x86 +http://svn.tudos.org/repos/tudos + + + +2009-05-20T14:32:55.606606Z +455 +l4check + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +a704ac0b-3a55-4d43-a2a9-7be6f07c34fb + +lib +dir + diff --git a/libdde_linux26/lib/src/arch/x86/.svn/format b/libdde_linux26/lib/src/arch/x86/.svn/format new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/.svn/format @@ -0,0 +1 @@ +9 diff --git a/libdde_linux26/lib/src/arch/x86/lib/.svn/all-wcprops b/libdde_linux26/lib/src/arch/x86/lib/.svn/all-wcprops new file mode 100644 index 00000000..61d9e4b5 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 71 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/x86/lib +END +semaphore_32.S +K 25 +svn:wc:ra_dav:version-url +V 86 +/repos/tudos/!svn/ver/455/trunk/l4/pkg/dde/linux26/lib/src/arch/x86/lib/semaphore_32.S +END diff --git a/libdde_linux26/lib/src/arch/x86/lib/.svn/entries b/libdde_linux26/lib/src/arch/x86/lib/.svn/entries new file mode 100644 index 00000000..ee8219b2 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/.svn/entries @@ -0,0 +1,62 @@ +9 + +dir +465 +http://svn.tudos.org/repos/tudos/trunk/l4/pkg/dde/linux26/lib/src/arch/x86/lib +http://svn.tudos.org/repos/tudos + + + +2009-05-20T14:32:55.606606Z +455 +l4check + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +a704ac0b-3a55-4d43-a2a9-7be6f07c34fb + +semaphore_32.S +file + + + + +2009-11-15T17:17:12.000000Z +8781a421c002516577c2888bc85b51e9 +2009-05-20T14:32:55.606606Z +455 +l4check + + + + + + + + + + + + + + + + + + + + + +2859 + diff --git a/libdde_linux26/lib/src/arch/x86/lib/.svn/format b/libdde_linux26/lib/src/arch/x86/lib/.svn/format new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/.svn/format @@ -0,0 +1 @@ +9 diff --git a/libdde_linux26/lib/src/arch/x86/lib/.svn/text-base/semaphore_32.S.svn-base b/libdde_linux26/lib/src/arch/x86/lib/.svn/text-base/semaphore_32.S.svn-base new file mode 100644 index 00000000..1850ca50 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/.svn/text-base/semaphore_32.S.svn-base @@ -0,0 +1,138 @@ +/* + * i386 semaphore implementation. + * + * (C) Copyright 1999 Linus Torvalds + * + * Portions Copyright 1999 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * rw semaphores implemented November 1999 by Benjamin LaHaise + */ + +#include +#include +#include +#include +#include + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + * + * %eax contains the semaphore pointer on entry. Save the C-clobbered + * registers (%eax, %edx and %ecx) except %eax whish is either a return + * value or just clobbered.. + */ +#ifndef DDE_LINUX + .section .sched.text, "ax" +#endif + +/* + * rw spinlock fallbacks + */ +#ifdef CONFIG_SMP +ENTRY(__write_lock_failed) + CFI_STARTPROC simple + FRAME +2: LOCK_PREFIX + addl $ RW_LOCK_BIAS,(%eax) +1: rep; nop + cmpl $ RW_LOCK_BIAS,(%eax) + jne 1b + LOCK_PREFIX + subl $ RW_LOCK_BIAS,(%eax) + jnz 2b + ENDFRAME + ret + CFI_ENDPROC + ENDPROC(__write_lock_failed) + +ENTRY(__read_lock_failed) + CFI_STARTPROC + FRAME +2: LOCK_PREFIX + incl (%eax) +1: rep; nop + cmpl $1,(%eax) + js 1b + LOCK_PREFIX + decl (%eax) + js 2b + ENDFRAME + ret + CFI_ENDPROC + ENDPROC(__read_lock_failed) + +#endif + +#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_down_read_failed) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + push %edx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edx,0 + call rwsem_down_read_failed + pop %edx + CFI_ADJUST_CFA_OFFSET -4 + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_down_read_failed) + +ENTRY(call_rwsem_down_write_failed) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + calll rwsem_down_write_failed + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_down_write_failed) + +ENTRY(call_rwsem_wake) + CFI_STARTPROC + decw %dx /* do nothing if still outstanding active readers */ + jnz 1f + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + call rwsem_wake + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 +1: ret + CFI_ENDPROC + ENDPROC(call_rwsem_wake) + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_downgrade_wake) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + push %edx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edx,0 + call rwsem_downgrade_wake + pop %edx + CFI_ADJUST_CFA_OFFSET -4 + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_downgrade_wake) + +#endif diff --git a/libdde_linux26/lib/src/arch/x86/lib/semaphore_32.S b/libdde_linux26/lib/src/arch/x86/lib/semaphore_32.S new file mode 100644 index 00000000..1850ca50 --- /dev/null +++ b/libdde_linux26/lib/src/arch/x86/lib/semaphore_32.S @@ -0,0 +1,138 @@ +/* + * i386 semaphore implementation. + * + * (C) Copyright 1999 Linus Torvalds + * + * Portions Copyright 1999 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * rw semaphores implemented November 1999 by Benjamin LaHaise + */ + +#include +#include +#include +#include +#include + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + * + * %eax contains the semaphore pointer on entry. Save the C-clobbered + * registers (%eax, %edx and %ecx) except %eax whish is either a return + * value or just clobbered.. + */ +#ifndef DDE_LINUX + .section .sched.text, "ax" +#endif + +/* + * rw spinlock fallbacks + */ +#ifdef CONFIG_SMP +ENTRY(__write_lock_failed) + CFI_STARTPROC simple + FRAME +2: LOCK_PREFIX + addl $ RW_LOCK_BIAS,(%eax) +1: rep; nop + cmpl $ RW_LOCK_BIAS,(%eax) + jne 1b + LOCK_PREFIX + subl $ RW_LOCK_BIAS,(%eax) + jnz 2b + ENDFRAME + ret + CFI_ENDPROC + ENDPROC(__write_lock_failed) + +ENTRY(__read_lock_failed) + CFI_STARTPROC + FRAME +2: LOCK_PREFIX + incl (%eax) +1: rep; nop + cmpl $1,(%eax) + js 1b + LOCK_PREFIX + decl (%eax) + js 2b + ENDFRAME + ret + CFI_ENDPROC + ENDPROC(__read_lock_failed) + +#endif + +#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_down_read_failed) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + push %edx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edx,0 + call rwsem_down_read_failed + pop %edx + CFI_ADJUST_CFA_OFFSET -4 + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_down_read_failed) + +ENTRY(call_rwsem_down_write_failed) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + calll rwsem_down_write_failed + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_down_write_failed) + +ENTRY(call_rwsem_wake) + CFI_STARTPROC + decw %dx /* do nothing if still outstanding active readers */ + jnz 1f + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + call rwsem_wake + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 +1: ret + CFI_ENDPROC + ENDPROC(call_rwsem_wake) + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_downgrade_wake) + CFI_STARTPROC + push %ecx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ecx,0 + push %edx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET edx,0 + call rwsem_downgrade_wake + pop %edx + CFI_ADJUST_CFA_OFFSET -4 + pop %ecx + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC + ENDPROC(call_rwsem_downgrade_wake) + +#endif -- cgit v1.2.3 From 85002dd39d65ff0c91bb6501197dc8067dbecaa5 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 1 Jan 2010 19:17:17 +0100 Subject: Change the path of header files. TODO We need to handle initcall properly. --- libdde_linux26/include/dde26.h | 2 +- libdde_linux26/include/linux/kernel.h | 4 +-- libdde_linux26/include/linux/mm.h | 2 +- libdde_linux26/include/linux/spinlock_types.h | 2 +- libdde_linux26/lib/src/arch/l4/init.c | 4 +-- libdde_linux26/lib/src/arch/l4/local.h | 36 +++++++++++++-------------- 6 files changed, 25 insertions(+), 25 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/include/dde26.h b/libdde_linux26/include/dde26.h index d1a4c171..ae64d909 100644 --- a/libdde_linux26/include/dde26.h +++ b/libdde_linux26/include/dde26.h @@ -1,7 +1,7 @@ #ifndef __DDE_26_H #define __DDE_26_H -#include +#include #define WARN_UNIMPL printk("unimplemented: %s\n", __FUNCTION__) diff --git a/libdde_linux26/include/linux/kernel.h b/libdde_linux26/include/linux/kernel.h index f5ec1ecf..573ed07c 100644 --- a/libdde_linux26/include/linux/kernel.h +++ b/libdde_linux26/include/linux/kernel.h @@ -162,7 +162,7 @@ extern long (*panic_blink)(long time); NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; #else -#include +#include #define panic ddekit_panic #endif extern void oops_enter(void); @@ -249,7 +249,7 @@ extern int printk_ratelimit(void); extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, unsigned int interval_msec); #else // DDE_LINUX -#include +#include #define printk ddekit_printf #endif #else diff --git a/libdde_linux26/include/linux/mm.h b/libdde_linux26/include/linux/mm.h index a3d0d3c6..8f61963c 100644 --- a/libdde_linux26/include/linux/mm.h +++ b/libdde_linux26/include/linux/mm.h @@ -15,7 +15,7 @@ #include #ifdef DDE_LINUX -#include +#include #endif struct mempolicy; diff --git a/libdde_linux26/include/linux/spinlock_types.h b/libdde_linux26/include/linux/spinlock_types.h index 51339e01..3d4dd796 100644 --- a/libdde_linux26/include/linux/spinlock_types.h +++ b/libdde_linux26/include/linux/spinlock_types.h @@ -101,7 +101,7 @@ typedef struct { #else -#include +#include typedef struct { ddekit_lock_t ddekit_lock; diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c index e89ef27f..79112f78 100644 --- a/libdde_linux26/lib/src/arch/l4/init.c +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -1,7 +1,7 @@ #include "local.h" -#include -#include +#include +#include #define DEBUG_PCI(msg, ...) ddekit_printf( "\033[33m"msg"\033[0m\n", ##__VA_ARGS__) diff --git a/libdde_linux26/lib/src/arch/l4/local.h b/libdde_linux26/lib/src/arch/l4/local.h index 35b3e449..d834a9db 100644 --- a/libdde_linux26/lib/src/arch/l4/local.h +++ b/libdde_linux26/lib/src/arch/l4/local.h @@ -3,24 +3,24 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #define DDE_DEBUG 1 #define DDE_FERRET 0 -- cgit v1.2.3 From 16b4a9b6e25500f2da14839b4494f82df4b0fc7f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 5 Jan 2010 16:30:03 +0100 Subject: correct the path of header files. --- libdde_linux26/lib/src/arch/l4/irq.c | 4 ---- libdde_linux26/lib/src/arch/l4/kmalloc.c | 6 ++---- libdde_linux26/lib/src/arch/l4/kmem_cache.c | 4 +--- libdde_linux26/lib/src/arch/l4/mm-helper.c | 5 ----- libdde_linux26/lib/src/arch/l4/net.c | 2 +- libdde_linux26/lib/src/arch/l4/page_alloc.c | 5 ----- libdde_linux26/lib/src/arch/l4/process.c | 4 ++-- libdde_linux26/lib/src/arch/l4/vmalloc.c | 4 +--- libdde_linux26/lib/src/net/core/dev.c | 2 +- 9 files changed, 8 insertions(+), 28 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/irq.c b/libdde_linux26/lib/src/arch/l4/irq.c index 0e565e54..9594b05c 100644 --- a/libdde_linux26/lib/src/arch/l4/irq.c +++ b/libdde_linux26/lib/src/arch/l4/irq.c @@ -12,10 +12,6 @@ #include #include /* memset() */ -/* DDEKit */ -#include -#include - /* local */ #include "dde26.h" #include "local.h" diff --git a/libdde_linux26/lib/src/arch/l4/kmalloc.c b/libdde_linux26/lib/src/arch/l4/kmalloc.c index 065c13c7..87d64878 100644 --- a/libdde_linux26/lib/src/arch/l4/kmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/kmalloc.c @@ -20,11 +20,9 @@ #include #include -/* DDEKit */ -#include -#include +#include "local.h" -#include +#include /* dummy */ int forbid_dac; diff --git a/libdde_linux26/lib/src/arch/l4/kmem_cache.c b/libdde_linux26/lib/src/arch/l4/kmem_cache.c index 1465ac6c..5e44c140 100644 --- a/libdde_linux26/lib/src/arch/l4/kmem_cache.c +++ b/libdde_linux26/lib/src/arch/l4/kmem_cache.c @@ -14,9 +14,7 @@ /* Linux */ #include -/* DDEKit */ -#include -#include +#include "local.h" /******************* diff --git a/libdde_linux26/lib/src/arch/l4/mm-helper.c b/libdde_linux26/lib/src/arch/l4/mm-helper.c index 68c0213b..cc4cc1d1 100644 --- a/libdde_linux26/lib/src/arch/l4/mm-helper.c +++ b/libdde_linux26/lib/src/arch/l4/mm-helper.c @@ -3,11 +3,6 @@ #include #include -/* DDEKit */ -#include -#include -#include - #include "local.h" int ioprio_best(unsigned short aprio, unsigned short bprio) diff --git a/libdde_linux26/lib/src/arch/l4/net.c b/libdde_linux26/lib/src/arch/l4/net.c index d6637d96..6e799119 100644 --- a/libdde_linux26/lib/src/arch/l4/net.c +++ b/libdde_linux26/lib/src/arch/l4/net.c @@ -8,7 +8,7 @@ * GNU General Public License 2. Please see the COPYING file for details. * ******************************************************************************/ -#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 0a2e3fdf..e887bd51 100644 --- a/libdde_linux26/lib/src/arch/l4/page_alloc.c +++ b/libdde_linux26/lib/src/arch/l4/page_alloc.c @@ -25,11 +25,6 @@ #include #include -/* DDEKit */ -#include -#include -#include - #include "local.h" unsigned long max_low_pfn; diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c index 5fe43b32..b5189cd4 100644 --- a/libdde_linux26/lib/src/arch/l4/process.c +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include diff --git a/libdde_linux26/lib/src/arch/l4/vmalloc.c b/libdde_linux26/lib/src/arch/l4/vmalloc.c index 134b80c3..4fa063f0 100644 --- a/libdde_linux26/lib/src/arch/l4/vmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/vmalloc.c @@ -15,9 +15,7 @@ /* Linux */ #include -/* DDEKit */ -#include -#include +#include "local.h" void *vmalloc(unsigned long size) { diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 22fdf4d7..1e9247c2 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -74,7 +74,7 @@ #ifdef DDE_LINUX #include "local.h" -#include +#include #endif #include -- 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') 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') 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 436fa4a5352cea7fc8eeafe2fc078031d731b471 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Wed, 13 Jan 2010 11:59:13 +0100 Subject: Remove the static declaration of initcall functions. --- 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/page_alloc.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/net/core/dev.c | 2 +- libdde_linux26/lib/src/net/core/net_namespace.c | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c b/libdde_linux26/contrib/arch/x86/kernel/pci-dma.c index 80e9f10e..3a26519b 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); -static int __init pci_iommu_init(void) +int __init pci_iommu_init(void) { calgary_iommu_init(); diff --git a/libdde_linux26/contrib/block/blk-ioc.c b/libdde_linux26/contrib/block/blk-ioc.c index e067a82a..b3292405 100644 --- a/libdde_linux26/contrib/block/blk-ioc.c +++ b/libdde_linux26/contrib/block/blk-ioc.c @@ -171,7 +171,7 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc) } EXPORT_SYMBOL(copy_io_context); -static int __init blk_ioc_init(void) +int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL); diff --git a/libdde_linux26/contrib/block/blk-settings.c b/libdde_linux26/contrib/block/blk-settings.c index ad0af33c..2178202f 100644 --- a/libdde_linux26/contrib/block/blk-settings.c +++ b/libdde_linux26/contrib/block/blk-settings.c @@ -463,7 +463,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask) } EXPORT_SYMBOL(blk_queue_update_dma_alignment); -static int __init blk_settings_init(void) +int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; blk_max_pfn = max_pfn - 1; diff --git a/libdde_linux26/contrib/block/blk-softirq.c b/libdde_linux26/contrib/block/blk-softirq.c index e9a18af7..34041d14 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); -static __init int blk_softirq_init(void) +__init int blk_softirq_init(void) { int i; diff --git a/libdde_linux26/contrib/block/noop-iosched.c b/libdde_linux26/contrib/block/noop-iosched.c index e78234a9..a7618fdb 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, }; -static int __init noop_init(void) +int __init noop_init(void) { DEBUG_MSG("here!"); elv_register(&elevator_noop); diff --git a/libdde_linux26/contrib/fs/bio.c b/libdde_linux26/contrib/fs/bio.c index a59a1488..7e0238b8 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) } } -static int __init init_bio(void) +int __init init_bio(void) { bio_slab_max = 2; bio_slab_nr = 0; diff --git a/libdde_linux26/contrib/mm/backing-dev.c b/libdde_linux26/contrib/mm/backing-dev.c index 32f604bc..25ebba9a 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, }; -static __init int bdi_class_init(void) +__init int bdi_class_init(void) { bdi_class = class_create(THIS_MODULE, "bdi"); bdi_class->dev_attrs = bdi_dev_attrs; diff --git a/libdde_linux26/contrib/net/core/neighbour.c b/libdde_linux26/contrib/net/core/neighbour.c index 4a90e322..02dc8bda 100644 --- a/libdde_linux26/contrib/net/core/neighbour.c +++ b/libdde_linux26/contrib/net/core/neighbour.c @@ -2808,7 +2808,7 @@ EXPORT_SYMBOL(neigh_sysctl_unregister); #endif /* CONFIG_SYSCTL */ -static int __init neigh_init(void) +int __init neigh_init(void) { rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL); rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL); diff --git a/libdde_linux26/lib/src/arch/l4/page_alloc.c b/libdde_linux26/lib/src/arch/l4/page_alloc.c index a418cc65..7c4faa0e 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, } -static void __init dde_page_cache_init(void) +void __init dde_page_cache_init(void) { printk("Initializing DDE page cache\n"); int i=0; diff --git a/libdde_linux26/lib/src/block/genhd.c b/libdde_linux26/lib/src/block/genhd.c index 9028c31c..f9a205f5 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; } -static int __init genhd_device_init(void) +int __init genhd_device_init(void) { int error; diff --git a/libdde_linux26/lib/src/drivers/pci/pci-driver.c b/libdde_linux26/lib/src/drivers/pci/pci-driver.c index ba4e5108..591d9489 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci-driver.c +++ b/libdde_linux26/lib/src/drivers/pci/pci-driver.c @@ -992,7 +992,7 @@ struct bus_type pci_bus_type = { .pm = PCI_PM_OPS_PTR, }; -static int __init pci_driver_init(void) +int __init pci_driver_init(void) { return bus_register(&pci_bus_type); } diff --git a/libdde_linux26/lib/src/drivers/pci/pci.c b/libdde_linux26/lib/src/drivers/pci/pci.c index 05c7b38d..9bf601c3 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; } -static int __init pci_setup(char *str) +int __init pci_setup(char *str) { #ifndef DDE_LINUX while (str) { diff --git a/libdde_linux26/lib/src/drivers/pci/probe.c b/libdde_linux26/lib/src/drivers/pci/probe.c index d68a3023..9cbc3bfb 100644 --- a/libdde_linux26/lib/src/drivers/pci/probe.c +++ b/libdde_linux26/lib/src/drivers/pci/probe.c @@ -100,7 +100,7 @@ static struct class pcibus_class = { .dev_release = &release_pcibus_dev, }; -static int __init pcibus_class_init(void) +int __init pcibus_class_init(void) { return class_register(&pcibus_class); } diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 7afb2553..e66f1da2 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -5184,7 +5184,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. */ -static int __init net_dev_init(void) +int __init net_dev_init(void) { int i, rc = -ENOMEM; diff --git a/libdde_linux26/lib/src/net/core/net_namespace.c b/libdde_linux26/lib/src/net/core/net_namespace.c index e1f05049..29f29621 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 -static int __init net_ns_init(void) +int __init net_ns_init(void) { struct net_generic *ng; int err; -- cgit v1.2.3 From 09c9ba0c95d9c8dfb9b1f4e1f907d3a60f710166 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Wed, 13 Jan 2010 12:10:23 +0100 Subject: don't initialize neighbor and genhd for now. --- libdde_linux26/lib/src/arch/l4/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c index 1d44bf97..f417febc 100644 --- a/libdde_linux26/lib/src/arch/l4/init.c +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -60,11 +60,11 @@ void l4dde26_do_initcalls(void) l4dde26_init_pci (); /* 1003: subsys_ */ net_dev_init (); - neigh_init (); +// neigh_init (); blk_ioc_init (); blk_settings_init (); blk_softirq_init (); - genhd_device_init (); +// genhd_device_init (); noop_init (); init_bio (); /* 1004: fs_ */ -- cgit v1.2.3 From a060d4fc63de2cafb94c94505b113e37dd94b805 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 16 Jan 2010 00:07:42 +0100 Subject: Initialize dde26 process. --- libdde_linux26/lib/src/arch/l4/init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/init.c b/libdde_linux26/lib/src/arch/l4/init.c index f417febc..195b1b23 100644 --- a/libdde_linux26/lib/src/arch/l4/init.c +++ b/libdde_linux26/lib/src/arch/l4/init.c @@ -47,6 +47,7 @@ void l4dde26_do_initcalls(void) // ddekit_do_initcalls(); /* 1000: pure_, core_ */ l4dde26_init (); + l4dde26_process_init (); l4dde26_init_timers (); net_ns_init (); dde_page_cache_init (); -- 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') 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 38471feb4f5f5127290d28fc97cb1f54f96a0ffe Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 26 Jan 2010 09:47:41 +0100 Subject: DDE Linux: Temporary solution to handle two buses. --- libdde_linux26/lib/src/arch/l4/pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index 2a0391f2..d5a1414f 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -26,6 +26,7 @@ static LIST_HEAD(pcidev_mappings); /** PCI bus */ static struct pci_bus *pci_bus = NULL; +static struct pci_bus *pci_bus1 = NULL; static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); @@ -178,11 +179,18 @@ void __init l4dde26_init_pci(void) { ddekit_pci_init(); + // TODO it's a temporary solution to handle 2 buses. + // we need to find a way to detect buses. pci_bus = pci_create_bus(NULL, 0, &dde_pcibus_ops, NULL); Assert(pci_bus); pci_do_scan_bus(pci_bus); + pci_bus1 = pci_create_bus(NULL, 2, &dde_pcibus_ops, NULL); + Assert(pci_bus1); + + pci_do_scan_bus(pci_bus1); + INITIALIZE_INITVAR(dde26_pci); } -- cgit v1.2.3 From 2bbc0548875321fa8660566254699cbab9aa00e9 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 29 Jan 2010 20:31:20 +0100 Subject: libdde_linux26 is adapted to be used by libmachdev. --- libdde_linux26/contrib/include/linux/skbuff.h | 5 ++ libdde_linux26/include/dde26_net.h | 9 ++- libdde_linux26/lib/src/Makefile | 1 + libdde_linux26/lib/src/arch/l4/mach_glue.c | 85 +++++++++++++++++++++++++++ libdde_linux26/lib/src/net/core/skbuff.c | 11 ++++ 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 libdde_linux26/lib/src/arch/l4/mach_glue.c (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/contrib/include/linux/skbuff.h b/libdde_linux26/contrib/include/linux/skbuff.h index 9dcf956a..a9e9534d 100644 --- a/libdde_linux26/contrib/include/linux/skbuff.h +++ b/libdde_linux26/contrib/include/linux/skbuff.h @@ -354,6 +354,11 @@ struct sk_buff { *data; unsigned int truesize; atomic_t users; + +#ifdef DDE_LINUX + void *del_data; + int (*pre_del_func) (struct sk_buff *, void *); +#endif }; #ifdef __KERNEL__ diff --git a/libdde_linux26/include/dde26_net.h b/libdde_linux26/include/dde26_net.h index 2c3847b8..4545e7cc 100644 --- a/libdde_linux26/include/dde26_net.h +++ b/libdde_linux26/include/dde26_net.h @@ -2,9 +2,10 @@ #define __DDE_26_NET_H #include +#include /** rx callback function */ -typedef int (*linux_rx_callback)(struct sk_buff *); +typedef int (*linux_rx_callback)(char *, int, struct net_device *); extern linux_rx_callback l4dde26_rx_callback; @@ -25,8 +26,10 @@ linux_rx_callback l4dde26_register_rx_callback(linux_rx_callback cb); */ static inline int l4dde26_do_rx_callback(struct sk_buff *s) { - if (l4dde26_rx_callback != NULL) - return l4dde26_rx_callback(s); + if (l4dde26_rx_callback != NULL) { + skb_push(s, s->dev->hard_header_len); + return l4dde26_rx_callback(s->data, s->len, s->dev); + } return 0; } diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile index b6670ed5..d06a8d6b 100644 --- a/libdde_linux26/lib/src/Makefile +++ b/libdde_linux26/lib/src/Makefile @@ -150,6 +150,7 @@ SRC_C_libdde_linux26.o.a += \ ################################################################## SRC_C_libdde_linux26_net.a += \ arch/l4/net.c \ + arch/l4/mach_glue.c \ drivers/net/mii.c \ net/core/dev.c \ net/core/dev_mcast.c \ diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c new file mode 100644 index 00000000..9130c550 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -0,0 +1,85 @@ +#include +#include + +#define D_INVALID_SIZE 2507 +#define D_NO_MEMORY 2508 + +/* List of sk_buffs waiting to be freed. */ +static struct sk_buff_head skb_done_list; + +struct net_device *search_netdev (char *name) +{ + struct net_device *dev; + struct net *net; + + read_lock(&dev_base_lock); + for_each_net(net) { + for_each_netdev(net, dev) { + if (!strcmp (name, dev->name) + && dev->base_addr && dev->base_addr != 0xffe0) + goto end; + } + } +end: + read_unlock(&dev_base_lock); + return dev; +} + +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev) +{ + struct sk_buff *skb; + + if (len == 0 || len > dev->mtu + dev->hard_header_len) + return D_INVALID_SIZE; + + /* Allocate a sk_buff. */ + skb = dev_alloc_skb (len); + if (!skb) + return D_NO_MEMORY; + + skb->del_data = del_data; + skb->pre_del_func = del_func; + + /* Copy user data. This is only required if it spans multiple pages. */ + skb->len = len; + skb->tail = skb->data + len; + skb->end = skb->tail; + + memcpy (skb->data, pkg_data, len); + + skb->dev = dev; + + return dev->netdev_ops->ndo_start_xmit(skb, dev); +} + +char *netdev_addr(struct net_device *dev) +{ + return dev->dev_addr; +} + +int netdev_flags(struct net_device *dev) +{ + return dev->flags; +} + +void *skb_reply(struct sk_buff *skb) +{ + return skb->del_data; +} + +void skb_done_head_init() +{ + skb_queue_head_init (&skb_done_list); +} + +struct sk_buff *skb_done_dequeue() +{ + return skb_dequeue (&skb_done_list); +} + +void skb_done_queue(struct sk_buff *skb) +{ + skb_queue_tail (&skb_done_list, skb); +} diff --git a/libdde_linux26/lib/src/net/core/skbuff.c b/libdde_linux26/lib/src/net/core/skbuff.c index 59b275b0..853b535b 100644 --- a/libdde_linux26/lib/src/net/core/skbuff.c +++ b/libdde_linux26/lib/src/net/core/skbuff.c @@ -421,6 +421,11 @@ static void skb_release_all(struct sk_buff *skb) void __kfree_skb(struct sk_buff *skb) { +#ifdef DDE_LINUX + if (skb->del_data && skb->pre_del_func + && skb->pre_del_func(skb, skb->del_data)) + return; +#endif skb_release_all(skb); kfree_skbmem(skb); } @@ -436,6 +441,12 @@ void kfree_skb(struct sk_buff *skb) { if (unlikely(!skb)) return; +#ifdef DDE_LINUX + if (atomic_read(&skb->users) == 0) { + __kfree_skb(skb); + return; + } +#endif if (likely(atomic_read(&skb->users) == 1)) smp_rmb(); else if (likely(!atomic_dec_and_test(&skb->users))) -- cgit v1.2.3 From 0160c09ad53e6d1e21d70c8c03c6ca6479737564 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 6 Feb 2010 07:51:42 +0100 Subject: fix a serious bug in dde_linux26. don't set `tail` in sk_buff. --- libdde_linux26/lib/src/arch/l4/mach_glue.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c index 9130c550..8f8b6fca 100644 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -45,7 +45,6 @@ int linux_pkg_xmit (char *pkg_data, int len, void *del_data, /* Copy user data. This is only required if it spans multiple pages. */ skb->len = len; skb->tail = skb->data + len; - skb->end = skb->tail; memcpy (skb->data, pkg_data, len); -- cgit v1.2.3 From 1288bc521d37d34d809ad46f4d14cc662bcfe688 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 27 Feb 2010 14:28:22 +0100 Subject: Use adapted dev_queue_xmit to transmit packets in DDE Linux. --- libdde_linux26/lib/src/arch/l4/mach_glue.c | 4 +++- libdde_linux26/lib/src/net/core/dev.c | 20 -------------------- 2 files changed, 3 insertions(+), 21 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c index 8f8b6fca..f3f56bda 100644 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -50,7 +50,9 @@ int linux_pkg_xmit (char *pkg_data, int len, void *del_data, skb->dev = dev; - return dev->netdev_ops->ndo_start_xmit(skb, dev); + dev_queue_xmit(skb); + // TODO how should I return errors? + return 0; } char *netdev_addr(struct net_device *dev) diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 65b4ba42..64917332 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -1777,8 +1777,6 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, if (ops->ndo_select_queue) queue_index = ops->ndo_select_queue(dev, skb); - else if (dev->real_num_tx_queues > 1) - queue_index = simple_tx_hash(dev, skb); skb_set_queue_mapping(skb, queue_index); return netdev_get_tx_queue(dev, queue_index); @@ -1813,7 +1811,6 @@ int dev_queue_xmit(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct netdev_queue *txq; - struct Qdisc *q; int rc = -ENOMEM; /* GSO will handle the following emulations directly. */ @@ -1851,27 +1848,10 @@ gso: rcu_read_lock_bh(); txq = dev_pick_tx(dev, skb); - q = rcu_dereference(txq->qdisc); #ifdef CONFIG_NET_CLS_ACT skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); #endif - if (q->enqueue) { - spinlock_t *root_lock = qdisc_lock(q); - - spin_lock(root_lock); - - if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) { - kfree_skb(skb); - rc = NET_XMIT_DROP; - } else { - rc = qdisc_enqueue_root(skb, q); - qdisc_run(q); - } - spin_unlock(root_lock); - - goto out; - } /* The device has no queue. Common case for software devices: loopback, all the sorts of tunnels... -- cgit v1.2.3 From a4bb3955579991dfb1ef5b8ffcc498b54671351e Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 27 Feb 2010 15:46:25 +0100 Subject: Use lock to protect pending softirq variable. This is a temporary solution. I should implement a correct mechanism to simulate cli/sti. --- libdde_linux26/lib/src/arch/l4/softirq.c | 13 +++++++++++-- libdde_linux26/lib/src/net/core/dev.c | 9 +++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/softirq.c b/libdde_linux26/lib/src/arch/l4/softirq.c index 21b36d17..be13422b 100644 --- a/libdde_linux26/lib/src/arch/l4/softirq.c +++ b/libdde_linux26/lib/src/arch/l4/softirq.c @@ -172,6 +172,7 @@ static void tasklet_hi_action(struct softirq_action *a) } } +ddekit_lock_t cli_lock; #define MAX_SOFTIRQ_RETRIES 10 @@ -186,6 +187,8 @@ void __do_softirq(void) /* reset softirq count */ set_softirq_pending(0); + ddekit_lock_unlock(&cli_lock); +// local_irq_enable(); /* While we have a softirq pending... */ while (pending) { @@ -197,6 +200,8 @@ void __do_softirq(void) /* remove pending flag for last softirq */ pending >>= 1; } +// local_irq_disable(); + ddekit_lock_lock(&cli_lock); /* Somebody might have scheduled another softirq in between * (e.g., an IRQ thread or another tasklet). */ @@ -209,10 +214,14 @@ void do_softirq(void) { unsigned long flags; - local_irq_save(flags); + if (cli_lock == NULL) + ddekit_lock_init_unlocked(&cli_lock); + ddekit_lock_lock(&cli_lock); +// local_irq_save(flags); if (local_softirq_pending()) __do_softirq(); - local_irq_restore(flags); +// local_irq_restore(flags); + ddekit_lock_unlock(&cli_lock); } /** Softirq thread function. diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 64917332..128f4d73 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -2611,11 +2611,16 @@ out: void __napi_schedule(struct napi_struct *n) { unsigned long flags; + extern ddekit_lock_t cli_lock; - local_irq_save(flags); + if (cli_lock == NULL) + ddekit_lock_init_unlocked(&cli_lock); + ddekit_lock_lock(&cli_lock); +// local_irq_save(flags); list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); - local_irq_restore(flags); +// local_irq_restore(flags); + ddekit_lock_unlock(&cli_lock); } EXPORT_SYMBOL(__napi_schedule); -- cgit v1.2.3 From fbb1c9f5d35a8b89bbebb55a4a49c3da2f189c05 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 28 Feb 2010 05:24:57 +0100 Subject: implement cli/sti with a lock. In order to avoid dead lock caused by spin_lock_irq or spin_lock_irqsave, I remove irq disabling in them. It's really unnecessary to do spin_lock_irq and spin_lock_irqsave any more because interrupt isn't handled in a real interrupt context. --- libdde_linux26/include/linux/spinlock.h | 7 ++--- libdde_linux26/lib/src/arch/l4/cli_sti.c | 49 +++++++++++++++++++++++++++++++- libdde_linux26/lib/src/arch/l4/softirq.c | 16 +++-------- libdde_linux26/lib/src/net/core/dev.c | 9 ++---- 4 files changed, 56 insertions(+), 25 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h index ab862f99..7fb7a251 100644 --- a/libdde_linux26/include/linux/spinlock.h +++ b/libdde_linux26/include/linux/spinlock.h @@ -394,7 +394,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_lock(lock) spin_lock(lock) #define write_lock(lock) spin_lock(lock) -#define spin_lock_irq(lock) local_irq_disable(); spin_lock(lock) +#define spin_lock_irq(lock) spin_lock(lock) #define spin_lock_bh(lock) spin_lock(lock) #define read_lock_irq(lock) spin_lock_irq(lock) #define read_lock_bh(lock) spin_lock_bh(lock) @@ -411,7 +411,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_unlock(lock) spin_unlock(lock) #define write_unlock(lock) spin_unlock(lock) -#define spin_unlock_irq(lock) spin_unlock(lock); local_irq_enable() +#define spin_unlock_irq(lock) spin_unlock(lock) #define spin_unlock_bh(lock) spin_unlock(lock) #define read_unlock_irq(lock) spin_unlock_irq(lock) #define read_unlock_bh(lock) spin_unlock_bh(lock) @@ -420,7 +420,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_lock_irqsave(lock, flags) \ do { \ - local_irq_save(flags); \ spin_lock(lock);\ } while (0); @@ -430,7 +429,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_unlock_irqrestore(lock, flags) \ do { \ spin_unlock(lock); \ - local_irq_restore(flags); \ } while (0); #define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) @@ -448,7 +446,6 @@ static int __lockfunc spin_trylock(spinlock_t *lock) #define spin_trylock_irqsave(lock, flags) \ ({ \ - local_irq_save(flags); \ spin_trylock(lock) ? \ 1 : ({ local_irq_restore(flags); 0; }); \ }) diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c index 81c4feea..3f5ba4cf 100644 --- a/libdde_linux26/lib/src/arch/l4/cli_sti.c +++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c @@ -4,6 +4,7 @@ /* IRQ lock reference counter */ static atomic_t _refcnt = ATOMIC_INIT(0); +static ddekit_lock_t cli_lock; /* Check whether IRQs are currently disabled. * @@ -15,6 +16,29 @@ int raw_irqs_disabled_flags(unsigned long flags) return ((int)flags > 0); } +/* If it does lock operation successfully, return > 0. Otherwise, 0. */ +static int nested_lock(ddekit_lock_t lock) +{ + int do_lock = 0; + + if (ddekit_lock_try_lock(&lock)) { /* if we cannot lock */ + /* check who hold the lock. */ + if (_ddekit_lock_owner(&lock) != (int) ddekit_thread_myself()) { + /* Someone else holds the lock, + * or by the time I try to lock again, + * the person has release the lock. */ + ddekit_lock_lock(&lock); + do_lock = 1; + } + /* If I hold the lock myself, I don't need to worry + * the lock will be released somewhere before I do it. */ + } + else + do_lock = 2; + + return do_lock; +} + /* Store the current flags state. * * This is done by returning the current refcnt. @@ -24,25 +48,48 @@ int raw_irqs_disabled_flags(unsigned long flags) */ unsigned long __raw_local_save_flags(void) { - return (unsigned long)atomic_read(&_refcnt); + unsigned long flags; + int do_lock = 0; + + if (cli_lock == NULL) + ddekit_lock_init_unlocked(&cli_lock); + /* It's important to do lock here. + * Otherwise, a thread might not get correct flags. */ + do_lock = nested_lock(cli_lock); + flags = (unsigned long)atomic_read(&_refcnt); + if (do_lock) + ddekit_lock_unlock(&cli_lock); + return flags; } /* Restore IRQ state. */ void raw_local_irq_restore(unsigned long flags) { + Assert(cli_lock != NULL); atomic_set(&_refcnt, flags); + if (flags == 0) + ddekit_lock_unlock(&cli_lock); } /* Disable IRQs by grabbing the IRQ lock. */ void raw_local_irq_disable(void) { + struct ddekit_thread *helder; + int is_print = 0; + + if (cli_lock == NULL) + ddekit_lock_init_unlocked(&cli_lock); + + nested_lock(cli_lock); atomic_inc(&_refcnt); } /* Unlock the IRQ lock until refcnt is 0. */ void raw_local_irq_enable(void) { + Assert(cli_lock != NULL); atomic_set(&_refcnt, 0); + ddekit_lock_unlock(&cli_lock); } diff --git a/libdde_linux26/lib/src/arch/l4/softirq.c b/libdde_linux26/lib/src/arch/l4/softirq.c index be13422b..67e8f5aa 100644 --- a/libdde_linux26/lib/src/arch/l4/softirq.c +++ b/libdde_linux26/lib/src/arch/l4/softirq.c @@ -172,8 +172,6 @@ static void tasklet_hi_action(struct softirq_action *a) } } -ddekit_lock_t cli_lock; - #define MAX_SOFTIRQ_RETRIES 10 /** Run softirq handlers @@ -187,8 +185,7 @@ void __do_softirq(void) /* reset softirq count */ set_softirq_pending(0); - ddekit_lock_unlock(&cli_lock); -// local_irq_enable(); + local_irq_enable(); /* While we have a softirq pending... */ while (pending) { @@ -200,8 +197,7 @@ void __do_softirq(void) /* remove pending flag for last softirq */ pending >>= 1; } -// local_irq_disable(); - ddekit_lock_lock(&cli_lock); + local_irq_disable(); /* Somebody might have scheduled another softirq in between * (e.g., an IRQ thread or another tasklet). */ @@ -214,14 +210,10 @@ void do_softirq(void) { unsigned long flags; - if (cli_lock == NULL) - ddekit_lock_init_unlocked(&cli_lock); - ddekit_lock_lock(&cli_lock); -// local_irq_save(flags); + local_irq_save(flags); if (local_softirq_pending()) __do_softirq(); -// local_irq_restore(flags); - ddekit_lock_unlock(&cli_lock); + local_irq_restore(flags); } /** Softirq thread function. diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 128f4d73..64917332 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -2611,16 +2611,11 @@ out: void __napi_schedule(struct napi_struct *n) { unsigned long flags; - extern ddekit_lock_t cli_lock; - if (cli_lock == NULL) - ddekit_lock_init_unlocked(&cli_lock); - ddekit_lock_lock(&cli_lock); -// local_irq_save(flags); + local_irq_save(flags); list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); -// local_irq_restore(flags); - ddekit_lock_unlock(&cli_lock); + local_irq_restore(flags); } EXPORT_SYMBOL(__napi_schedule); -- cgit v1.2.3 From 7a7787bfb9c776da1a2597f5f723846d004de78d Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 6 Apr 2010 04:24:31 +0200 Subject: set memory allocated by ddekit_large_malloc to zero --- libdde_linux26/lib/src/arch/l4/kmalloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/kmalloc.c b/libdde_linux26/lib/src/arch/l4/kmalloc.c index 87d64878..0e94fb97 100644 --- a/libdde_linux26/lib/src/arch/l4/kmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/kmalloc.c @@ -134,9 +134,12 @@ void *__kmalloc(size_t size, gfp_t flags) if (cache) /* allocate from cache */ p = kmem_cache_alloc(cache, flags); - else + else { /* no cache for this size - use ddekit malloc */ p = ddekit_large_malloc(size); + if (flags & __GFP_ZERO) + memset (p, 0, size); + } ddekit_log(DEBUG_MALLOC, "size=%d, cache=%p (%d) => %p", size, cache, cache ? kmem_cache_size(cache) : 0, p); -- cgit v1.2.3 From d31e486426aed7952b3468a63f2e81735d09943c Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 6 Apr 2010 04:33:16 +0200 Subject: implement dump_stack in libddekit with backtrace. --- libdde_linux26/lib/src/arch/l4/process.c | 4 ---- libddekit/include/ddekit/printf.h | 2 ++ libddekit/printf.c | 12 ++++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c index b5189cd4..ac700f82 100644 --- a/libdde_linux26/lib/src/arch/l4/process.c +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -220,10 +220,6 @@ void do_exit(long code) ** Misc functions ** *****************************************************************************/ -void dump_stack(void) -{ -} - char *get_task_comm(char *buf, struct task_struct *tsk) { diff --git a/libddekit/include/ddekit/printf.h b/libddekit/include/ddekit/printf.h index 35b0dfa1..6dafa18d 100644 --- a/libddekit/include/ddekit/printf.h +++ b/libddekit/include/ddekit/printf.h @@ -18,6 +18,8 @@ int ddekit_printf(const char *fmt, ...); */ int ddekit_vprintf(const char *fmt, va_list va); +void dump_stack(void); + /** Log function and message. * \ingroup DDEKit_util */ diff --git a/libddekit/printf.c b/libddekit/printf.c index dacc65e6..c4a8b718 100644 --- a/libddekit/printf.c +++ b/libddekit/printf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "ddekit/printf.h" @@ -93,3 +94,14 @@ int log_init () return 0; } + +void dump_stack() +{ +#define NUM_TRACES 16 + void *trace[NUM_TRACES]; + int trace_size = 0; + + fprintf (stderr, "dump the stack\n"); + trace_size = backtrace(trace, NUM_TRACES); + backtrace_symbols_fd(trace, trace_size, 2); +} -- cgit v1.2.3 From 6dc9cfc88e514e367ff2413d8859b2337e286ce9 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 6 Apr 2010 04:36:51 +0200 Subject: Use pci_set_master in linux. --- libdde_linux26/lib/src/arch/l4/pci.c | 16 ++++++++++++---- libdde_linux26/lib/src/drivers/pci/pci.c | 2 -- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index d5a1414f..1cd64a7d 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -132,13 +132,21 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) //WARN_UNIMPL; } -void pci_set_master(struct pci_dev *dev) +static unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) { - CHECK_INITVAR(dde26_pci); - WARN_UNIMPL; + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } - int pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; diff --git a/libdde_linux26/lib/src/drivers/pci/pci.c b/libdde_linux26/lib/src/drivers/pci/pci.c index f67bf734..9350ffed 100644 --- a/libdde_linux26/lib/src/drivers/pci/pci.c +++ b/libdde_linux26/lib/src/drivers/pci/pci.c @@ -1731,7 +1731,6 @@ int pci_request_regions(struct pci_dev *pdev, const char *res_name) return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name); } -#ifndef DDE_LINUX /** * pci_request_regions_exclusive - Reserved PCI I/O and memory resources * @pdev: PCI device whose resources are to be reserved @@ -1792,7 +1791,6 @@ void pci_clear_master(struct pci_dev *dev) { __pci_set_master(dev, false); } -#endif /* DDE_LINUX */ #ifdef PCI_DISABLE_MWI int pci_set_mwi(struct pci_dev *dev) -- cgit v1.2.3 From 045fb6a578e0e4d97f0e581bbf514654686a86c1 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 4 May 2010 15:56:46 +0200 Subject: Add printing. --- dde_e1000/e1000_hw.c | 3 +++ dde_e1000/e1000_main.c | 33 ++++++++++++++++++++++++++++++-- libdde_linux26/lib/src/arch/l4/kmalloc.c | 11 ++++++++++- libdde_linux26/lib/src/arch/l4/res.c | 8 ++++++++ libdde_linux26/lib/src/net/core/skbuff.c | 9 +++++++-- libmachdev/net.c | 17 ++++++++++++---- 6 files changed, 72 insertions(+), 9 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/dde_e1000/e1000_hw.c b/dde_e1000/e1000_hw.c index e1a3fc13..27ed37d4 100644 --- a/dde_e1000/e1000_hw.c +++ b/dde_e1000/e1000_hw.c @@ -5627,6 +5627,7 @@ s32 e1000_read_mac_addr(struct e1000_hw *hw) DEBUGFUNC("e1000_read_mac_addr"); + printk("mac address: "); for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { offset = i >> 1; if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { @@ -5635,7 +5636,9 @@ s32 e1000_read_mac_addr(struct e1000_hw *hw) } hw->perm_mac_addr[i] = (u8)(eeprom_data & 0x00FF); hw->perm_mac_addr[i+1] = (u8)(eeprom_data >> 8); + printk("%x%x ", hw->perm_mac_addr[i], hw->perm_mac_addr[i+1]); } + printk("\n"); switch (hw->mac_type) { default: diff --git a/dde_e1000/e1000_main.c b/dde_e1000/e1000_main.c index f25a5367..3f608476 100644 --- a/dde_e1000/e1000_main.c +++ b/dde_e1000/e1000_main.c @@ -328,13 +328,15 @@ static void e1000_update_mng_vlan(struct e1000_adapter *adapter) E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { e1000_vlan_rx_add_vid(netdev, vid); adapter->mng_vlan_id = vid; - } else + } else { adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + } if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) + !vlan_group_get_device(adapter->vlgrp, old_vid)) { e1000_vlan_rx_kill_vid(netdev, old_vid); + } } else adapter->mng_vlan_id = vid; } @@ -937,7 +939,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* do not allocate ioport bars when not needed */ need_ioport = e1000_is_need_ioport(pdev); + printk("do we need ioport? %d\n", need_ioport); if (need_ioport) { + printk("pci_enable_device will be called\n"); bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); err = pci_enable_device(pdev); } else { @@ -947,6 +951,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) return err; + printk("bars: %x\n", bars); if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { pci_using_dac = 1; @@ -998,6 +1003,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, continue; if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { hw->io_base = pci_resource_start(pdev, i); + printk("io base: %p, i: %d\n", + hw->io_base, i); break; } } @@ -1084,6 +1091,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, */ memset(hw->mac_addr, 0, netdev->addr_len); } else { + printk("succeed to validate eeprom\n"); /* copy the MAC address out of the EEPROM */ if (e1000_read_mac_addr(hw)) DPRINTK(PROBE, ERR, "EEPROM Read Error\n"); @@ -1585,6 +1593,8 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, txdr->size = ALIGN(txdr->size, 4096); txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); + printk("allocate %d bytes for transmit desc ring: %p\n", + txdr->size, txdr->desc); if (!txdr->desc) { setup_tx_desc_die: vfree(txdr->buffer_info); @@ -1804,6 +1814,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, rxdr->size = rxdr->count * desc_len; rxdr->size = ALIGN(rxdr->size, 4096); + printk("we allocate %d descriptors for rx\n", rxdr->count); rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); if (!rxdr->desc) { @@ -3194,6 +3205,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) int tso; unsigned int f; + printk("try to send a packet\n"); /* This goes back to the question of how to logically map a tx queue * to a flow. Right now, performance is impacted slightly negatively * if using multiple tx queues. If the stack breaks away from a @@ -3671,6 +3683,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) struct e1000_hw *hw = &adapter->hw; u32 icr = er32(ICR); + printk("e1000_intr_msi is called\n"); /* in NAPI mode read ICR disables interrupts using IAM */ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { @@ -3717,6 +3730,7 @@ static irqreturn_t e1000_intr(int irq, void *data) if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags))) return IRQ_NONE; /* Not our interrupt */ + printk("e1000 gets an interrupt\n"); /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is * not set, then the adapter didn't send an interrupt */ if (unlikely(hw->mac_type >= e1000_82571 && @@ -3799,6 +3813,8 @@ static int e1000_clean(struct napi_struct *napi, int budget) e1000_irq_enable(adapter); } + printk("e1000_clean: budget: %d, work_done: %d, tx_cleaned: %d\n", + budget, work_done, tx_cleaned); return work_done; } @@ -3823,6 +3839,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, eop_desc = E1000_TX_DESC(*tx_ring, eop); while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { + printk("e1000_clean_tx_irq: check desc %d\n", eop); for (cleaned = false; !cleaned; ) { tx_desc = E1000_TX_DESC(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; @@ -4090,6 +4107,8 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { + printk("cleaned_count in the loop: %d\n", + cleaned_count); adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); cleaned_count = 0; } @@ -4129,6 +4148,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, unsigned int i; unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN; + printk("e1000_alloc_rx_buffers is called\n"); i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; @@ -4143,6 +4163,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; + printk("check point 1\n"); break; } @@ -4156,6 +4177,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, /* Failed allocation, critical failure */ if (!skb) { dev_kfree_skb(oldskb); + printk("check point 2\n"); break; } @@ -4163,6 +4185,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, /* give up */ dev_kfree_skb(skb); dev_kfree_skb(oldskb); + printk("check point 3\n"); break; /* while !buffer_info->skb */ } @@ -4198,6 +4221,7 @@ map_skb: adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); + printk("check point 4\n"); break; /* while !buffer_info->skb */ } rx_desc = E1000_RX_DESC(*rx_ring, i); @@ -4208,7 +4232,10 @@ map_skb: buffer_info = &rx_ring->buffer_info[i]; } + printk("cleaned_count: %d\n", cleaned_count); if (likely(rx_ring->next_to_use != i)) { + printk("old rx_ring next_to_use: %d, new one: %d\n", + rx_ring->next_to_use, i); rx_ring->next_to_use = i; if (unlikely(i-- == 0)) i = (rx_ring->count - 1); @@ -4452,6 +4479,8 @@ static void e1000_vlan_rx_register(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; u32 ctrl, rctl; + printk ("********e1000_vlan_rx_register. grp: %p\n", grp); + if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); adapter->vlgrp = grp; diff --git a/libdde_linux26/lib/src/arch/l4/kmalloc.c b/libdde_linux26/lib/src/arch/l4/kmalloc.c index 0e94fb97..816f443c 100644 --- a/libdde_linux26/lib/src/arch/l4/kmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/kmalloc.c @@ -131,14 +131,23 @@ void *__kmalloc(size_t size, gfp_t flags) struct kmem_cache *cache = find_cache(size); void **p; - if (cache) + if (cache) { /* allocate from cache */ p = kmem_cache_alloc(cache, flags); + if (!p) { + printk("__kmalloc: kmem_cache_alloc %s fails\n", + ((char **)cache)[0]); + } + } else { /* no cache for this size - use ddekit malloc */ p = ddekit_large_malloc(size); if (flags & __GFP_ZERO) memset (p, 0, size); + if (!p) { + printk("__kmalloc: ddekit_large_malloc %d fails\n", + size); + } } ddekit_log(DEBUG_MALLOC, "size=%d, cache=%p (%d) => %p", diff --git a/libdde_linux26/lib/src/arch/l4/res.c b/libdde_linux26/lib/src/arch/l4/res.c index fbd2d09b..a2ffb98f 100644 --- a/libdde_linux26/lib/src/arch/l4/res.c +++ b/libdde_linux26/lib/src/arch/l4/res.c @@ -99,8 +99,12 @@ struct resource * __request_region(struct resource *parent, switch (parent->flags) { case IORESOURCE_IO: + printk("IO: name: %s, start: %x, len: %d\n", + name, start, n); return l4dde26_request_region(start, n, name); case IORESOURCE_MEM: + printk("MEM: name: %s, start: %x, len: %d\n", + name, start, n); return l4dde26_request_mem_region(start, n, name); } @@ -161,7 +165,11 @@ void __iomem * ioremap(unsigned long phys_addr, unsigned long size) struct dde_mem_region *mreg = list_entry(pos, struct dde_mem_region, list); if (mreg->pa <= phys_addr && mreg->pa + mreg->size >= phys_addr + size) + { + printk ("ioremap: phys: %x <-> virt: %x\n", phys_addr, + (mreg->va + (phys_addr - mreg->pa))); return (void *)(mreg->va + (phys_addr - mreg->pa)); + } } return NULL; diff --git a/libdde_linux26/lib/src/net/core/skbuff.c b/libdde_linux26/lib/src/net/core/skbuff.c index 2f65e534..40d64a88 100644 --- a/libdde_linux26/lib/src/net/core/skbuff.c +++ b/libdde_linux26/lib/src/net/core/skbuff.c @@ -180,14 +180,19 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, /* Get the HEAD */ skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); - if (!skb) + if (!skb) { + printk("kmem_cache_alloc_node fails\n"); goto out; + } size = SKB_DATA_ALIGN(size); data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), gfp_mask, node); - if (!data) + if (!data) { + printk("kmalloc_node_track_caller %d fails\n", + size + sizeof(struct skb_shared_info)); goto nodata; + } /* * Only clear those fields we need to clear, not those that we will diff --git a/libmachdev/net.c b/libmachdev/net.c index 9a367a6b..ca6bca63 100644 --- a/libmachdev/net.c +++ b/libmachdev/net.c @@ -122,7 +122,7 @@ struct net_data *nd_head; extern struct device_emulation_ops linux_net_emulation_ops; -static int print_packet_size = 0; +static int print_packet_size = 1; mach_msg_type_t header_type = { @@ -299,7 +299,10 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, /* Search for the device. */ dev = search_netdev (name); if (!dev) - return D_NO_SUCH_DEVICE; + { + fprintf (stderr, "after search_netdev: cannot find %s\n", name); + return D_NO_SUCH_DEVICE; + } /* Allocate and initialize device data if this is the first open. */ nd = search_nd (dev); @@ -307,7 +310,10 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, { err = create_device_port (sizeof (*nd), &nd); if (err) - goto out; + { + fprintf (stderr, "after create_device_port: cannot create a port\n"); + goto out; + } nd->dev = dev; nd->device.emul_data = nd; @@ -333,7 +339,10 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, #endif if (dev_open(dev) < 0) - err = D_NO_SUCH_DEVICE; + { + fprintf (stderr, "after dev_open: cannot open the device\n"); + err = D_NO_SUCH_DEVICE; + } out: if (err) -- cgit v1.2.3 From 6579834b6c314d2a40f205769b3047bf12839e88 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Wed, 5 May 2010 14:31:35 +0200 Subject: fix a bug in searching network devices. --- libdde_linux26/lib/src/arch/l4/mach_glue.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c index f3f56bda..ae91ef98 100644 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -10,19 +10,25 @@ static struct sk_buff_head skb_done_list; struct net_device *search_netdev (char *name) { struct net_device *dev; + struct net_device *found = NULL; struct net *net; + printk("search device %s\n", name); read_lock(&dev_base_lock); for_each_net(net) { for_each_netdev(net, dev) { - if (!strcmp (name, dev->name) - && dev->base_addr && dev->base_addr != 0xffe0) + printk("there is device %s, base addr: %x\n", + dev->name, dev->base_addr); + if (!strcmp (name, dev->name)) + { + found = dev; goto end; + } } } end: read_unlock(&dev_base_lock); - return dev; + return found; } int linux_pkg_xmit (char *pkg_data, int len, void *del_data, -- cgit v1.2.3 From ce31200bf83de4cb46fb8fb8c744c6e1c985588a Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Wed, 5 May 2010 14:33:45 +0200 Subject: explicitly show pcibios_enable_device isn't implemented. --- libdde_linux26/lib/src/arch/l4/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/pci.c b/libdde_linux26/lib/src/arch/l4/pci.c index 1cd64a7d..c393fd3a 100644 --- a/libdde_linux26/lib/src/arch/l4/pci.c +++ b/libdde_linux26/lib/src/arch/l4/pci.c @@ -174,7 +174,8 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pcibios_enable_irq(dev); #endif - return 0; + WARN_UNIMPL; + return -1; } /******************************************************************************************* -- cgit v1.2.3 From 74ce2169ff3136ec141c88b07b7f907d7866d49d Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 4 Jun 2010 07:40:52 +0200 Subject: return linux errno in linux_pkg_xmit. --- libdde_linux26/lib/src/arch/l4/mach_glue.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c index ae91ef98..48373a90 100644 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ b/libdde_linux26/lib/src/arch/l4/mach_glue.c @@ -1,9 +1,6 @@ #include #include -#define D_INVALID_SIZE 2507 -#define D_NO_MEMORY 2508 - /* List of sk_buffs waiting to be freed. */ static struct sk_buff_head skb_done_list; @@ -38,12 +35,12 @@ int linux_pkg_xmit (char *pkg_data, int len, void *del_data, struct sk_buff *skb; if (len == 0 || len > dev->mtu + dev->hard_header_len) - return D_INVALID_SIZE; + return EINVAL; /* Allocate a sk_buff. */ skb = dev_alloc_skb (len); if (!skb) - return D_NO_MEMORY; + return ENOMEM; skb->del_data = del_data; skb->pre_del_func = del_func; @@ -56,9 +53,7 @@ int linux_pkg_xmit (char *pkg_data, int len, void *del_data, skb->dev = dev; - dev_queue_xmit(skb); - // TODO how should I return errors? - return 0; + return dev_queue_xmit(skb); } char *netdev_addr(struct net_device *dev) -- cgit v1.2.3 From 21bf6f025d94c2987dfe30a0b327b6dfab7a8bff Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 4 Jun 2010 16:51:24 +0200 Subject: support block devices in the DDE library. --- libdde_linux26/lib/src/Makefile | 3 +- libdde_linux26/lib/src/arch/l4/mach_glue.c | 87 ---------- libdde_linux26/lib/src/mach_glue/block.c | 77 +++++++++ libdde_linux26/lib/src/mach_glue/net.c | 87 ++++++++++ libmachdev/Makefile | 2 +- libmachdev/block.c | 250 +++++++++++++++++++++++++++++ libmachdev/mach_glue.h | 30 ++++ libmachdev/machdev.h | 1 + libmachdev/net.c | 19 +-- windhoek/Makefile | 4 +- windhoek/main.c | 1 + 11 files changed, 453 insertions(+), 108 deletions(-) delete mode 100644 libdde_linux26/lib/src/arch/l4/mach_glue.c create mode 100644 libdde_linux26/lib/src/mach_glue/block.c create mode 100644 libdde_linux26/lib/src/mach_glue/net.c create mode 100644 libmachdev/block.c create mode 100644 libmachdev/mach_glue.h (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile index 3743f91b..947f11b9 100644 --- a/libdde_linux26/lib/src/Makefile +++ b/libdde_linux26/lib/src/Makefile @@ -150,7 +150,7 @@ SRC_C_libdde_linux26.o.a += \ ################################################################## SRC_C_libdde_linux26_net.a += \ arch/l4/net.c \ - arch/l4/mach_glue.c \ + mach_glue/net.c \ drivers/net/mii.c \ net/core/dev.c \ net/core/dev_mcast.c \ @@ -180,6 +180,7 @@ SRC_C_libdde_linux26_sound.a += \ # SRC_C_libdde_linux26_block.a += \ arch/l4/inodes.c \ + mach_glue/block.c \ block/blk-barrier.c \ block/blk-core.c \ block/blk-exec.c \ diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c deleted file mode 100644 index 48373a90..00000000 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include - -/* List of sk_buffs waiting to be freed. */ -static struct sk_buff_head skb_done_list; - -struct net_device *search_netdev (char *name) -{ - struct net_device *dev; - struct net_device *found = NULL; - struct net *net; - - printk("search device %s\n", name); - read_lock(&dev_base_lock); - for_each_net(net) { - for_each_netdev(net, dev) { - printk("there is device %s, base addr: %x\n", - dev->name, dev->base_addr); - if (!strcmp (name, dev->name)) - { - found = dev; - goto end; - } - } - } -end: - read_unlock(&dev_base_lock); - return found; -} - -int linux_pkg_xmit (char *pkg_data, int len, void *del_data, - int (*del_func) (struct sk_buff *, void *), - struct net_device *dev) -{ - struct sk_buff *skb; - - if (len == 0 || len > dev->mtu + dev->hard_header_len) - return EINVAL; - - /* Allocate a sk_buff. */ - skb = dev_alloc_skb (len); - if (!skb) - return ENOMEM; - - skb->del_data = del_data; - skb->pre_del_func = del_func; - - /* Copy user data. This is only required if it spans multiple pages. */ - skb->len = len; - skb->tail = skb->data + len; - - memcpy (skb->data, pkg_data, len); - - skb->dev = dev; - - return dev_queue_xmit(skb); -} - -char *netdev_addr(struct net_device *dev) -{ - return dev->dev_addr; -} - -int netdev_flags(struct net_device *dev) -{ - return dev->flags; -} - -void *skb_reply(struct sk_buff *skb) -{ - return skb->del_data; -} - -void skb_done_head_init() -{ - skb_queue_head_init (&skb_done_list); -} - -struct sk_buff *skb_done_dequeue() -{ - return skb_dequeue (&skb_done_list); -} - -void skb_done_queue(struct sk_buff *skb) -{ - skb_queue_tail (&skb_done_list, skb); -} diff --git a/libdde_linux26/lib/src/mach_glue/block.c b/libdde_linux26/lib/src/mach_glue/block.c new file mode 100644 index 00000000..7eac7e46 --- /dev/null +++ b/libdde_linux26/lib/src/mach_glue/block.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +struct gendisk *find_disk_by_name (char *); +void dde_page_cache_add (struct page *); + +struct block_device *open_block_dev (char *name, int part, fmode_t mode) +{ + struct gendisk *disk = find_disk_by_name (name); + dev_t devid = MKDEV (disk->major, disk->first_minor + part); + return open_by_devnum (devid, mode); +} + +/* write a piece of data to a block device. + * DATA must be in one page. + * SECTORNR: the writing location in sectors. */ +int block_dev_write (struct block_device *dev, int sectornr, + char *data, int count, void (*write_done (int err))) +{ + int err = 0; + struct bio *bio; + struct page *page; + int i; + + void end_bio (struct bio *bio, int err) + { + write_done (err); + } + + assert (count <= PAGE_SIZE); + bio = bio_alloc (GFP_NOIO, 1); + if (bio == NULL) + { + err = ENOMEM; + goto out; + } + + page = kmalloc (sizeof (*page), GFP_KERNEL); + if (page == NULL) + { + err = ENOMEM; + goto out; + } + + bio->bi_sector = sectornr; + bio->bi_bdev = dev; + page->virtual = data; + dde_page_cache_add (page); + bio->bi_io_vec[0].bv_page = page; + bio->bi_io_vec[0].bv_len = count; + bio->bi_io_vec[0].bv_offset = (int) data & ~PAGE_MASK; + + bio->bi_vcnt = 1; + bio->bi_idx = 0; + bio->bi_size = count; + + bio->bi_end_io = end_bio; + bio->bi_private = NULL; + bio_get (bio); + submit_bio (WRITE, bio); + if (bio_flagged (bio, BIO_EOPNOTSUPP)) + { + err = -EOPNOTSUPP; + goto out; + } + bio_put (bio); +out: + if (err) + { + if (bio) + bio_put (bio); + kfree (page); + } + return err; +} diff --git a/libdde_linux26/lib/src/mach_glue/net.c b/libdde_linux26/lib/src/mach_glue/net.c new file mode 100644 index 00000000..48373a90 --- /dev/null +++ b/libdde_linux26/lib/src/mach_glue/net.c @@ -0,0 +1,87 @@ +#include +#include + +/* List of sk_buffs waiting to be freed. */ +static struct sk_buff_head skb_done_list; + +struct net_device *search_netdev (char *name) +{ + struct net_device *dev; + struct net_device *found = NULL; + struct net *net; + + printk("search device %s\n", name); + read_lock(&dev_base_lock); + for_each_net(net) { + for_each_netdev(net, dev) { + printk("there is device %s, base addr: %x\n", + dev->name, dev->base_addr); + if (!strcmp (name, dev->name)) + { + found = dev; + goto end; + } + } + } +end: + read_unlock(&dev_base_lock); + return found; +} + +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev) +{ + struct sk_buff *skb; + + if (len == 0 || len > dev->mtu + dev->hard_header_len) + return EINVAL; + + /* Allocate a sk_buff. */ + skb = dev_alloc_skb (len); + if (!skb) + return ENOMEM; + + skb->del_data = del_data; + skb->pre_del_func = del_func; + + /* Copy user data. This is only required if it spans multiple pages. */ + skb->len = len; + skb->tail = skb->data + len; + + memcpy (skb->data, pkg_data, len); + + skb->dev = dev; + + return dev_queue_xmit(skb); +} + +char *netdev_addr(struct net_device *dev) +{ + return dev->dev_addr; +} + +int netdev_flags(struct net_device *dev) +{ + return dev->flags; +} + +void *skb_reply(struct sk_buff *skb) +{ + return skb->del_data; +} + +void skb_done_head_init() +{ + skb_queue_head_init (&skb_done_list); +} + +struct sk_buff *skb_done_dequeue() +{ + return skb_dequeue (&skb_done_list); +} + +void skb_done_queue(struct sk_buff *skb) +{ + skb_queue_tail (&skb_done_list, skb); +} diff --git a/libmachdev/Makefile b/libmachdev/Makefile index 2bd294ad..7475d041 100644 --- a/libmachdev/Makefile +++ b/libmachdev/Makefile @@ -20,7 +20,7 @@ makemode := library libname = libmachdev SRCS = deviceUser.c machUser.c net.c ds_routines.c queue.c trivfs_server.c \ - device_replyUser.c deviceServer.c notifyServer.c misc.c + device_replyUser.c deviceServer.c notifyServer.c misc.c block.c LCLHDRS = dev_hdr.h device_emul.h ds_routines.h vm_param.h \ util.h queue.h io_req.h if_ether.h machdev.h linux-errno.h \ errno-base.h diff --git a/libmachdev/block.c b/libmachdev/block.c new file mode 100644 index 00000000..54048fde --- /dev/null +++ b/libmachdev/block.c @@ -0,0 +1,250 @@ +/* + * Linux block driver support. + * + * Copyright (C) 1996 The University of Utah and the Computer Systems + * Laboratory at the University of Utah (CSL) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Shantanu Goel, University of Utah CSL + */ + +#include +#include +#include + +#include "mach_U.h" + +#include +#include + +#define MACH_INCLUDE + +#include + +#include "vm_param.h" +#include "device_reply_U.h" +#include "dev_hdr.h" +#include "util.h" +#include "mach_glue.h" + +/* One of these is associated with each open instance of a device. */ +struct block_data +{ + struct port_info port; /* device port */ + struct emul_device device; /* generic device structure */ + dev_mode_t mode; + struct block_device *dev; +}; + +/* Return a send right associated with network device ND. */ +static mach_port_t +dev_to_port (void *nd) +{ + return (nd + ? ports_get_send_right (nd) + : MACH_PORT_NULL); +} + +extern struct device_emulation_ops linux_block_emulation_ops; + +#define DISK_NAME_LEN 32 + +/* Parse the device NAME. + Set *SLICE to be the DOS partition and + *PART the BSD/Mach partition, if any. */ +static char * +translate_name (char *name, int *slice, int *part) +{ + char *p, *q, *end; + char *ret; + int disk_num; + + /* Parse name into name, unit, DOS partition (slice) and partition. */ + for (*slice = 0, *part = -1, p = name; isalpha (*p); p++) + ; + if (p == name || ! isdigit (*p)) + return NULL; + end = p; + disk_num = strtol (p, &p, 0); + if (disk_num < 0 || disk_num > 26) + return NULL; +// do +// p++; +// while (isdigit (*p)); + if (*p) + { + q = p; + if (*q == 's' && isdigit (*(q + 1))) + { + q++; + do + *slice = *slice * 10 + *q++ - '0'; + while (isdigit (*q)); + if (! *q) + goto find_major; + } + if (! isalpha (*q) || *(q + 1)) + return NULL; + *part = *q - 'a'; + } + +find_major: + ret = malloc (DISK_NAME_LEN); + sprintf (ret, "hd%c", 'a' + disk_num); + return ret; +} + +static io_return_t +device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, + dev_mode_t mode, char *name, device_t *devp) +{ + io_return_t err = D_SUCCESS; + struct block_data *bd = NULL; + int slice, part; + char *dev_name = NULL; + + dev_name = translate_name (name, &slice, &part); + + // TODO when the port isn't used by clients, it should be destroyed. + err = create_device_port (sizeof (*bd), &bd); + if (err) + { + ddekit_printf ("after create_device_port: cannot create a port\n"); + goto out; + } + bd->dev = open_block_dev (dev_name, slice, mode); + if (bd->dev < 0) + { + ddekit_printf ("open_block_dev fails with %d\n", bd->dev); + err = linux_to_mach_error (err); + goto out; + } + bd->device.emul_data = bd; + bd->device.emul_ops = &linux_block_emulation_ops; + bd->mode = mode; + +out: + free (dev_name); + if (err) + { + if (bd) + { + ports_destroy_right (bd); + bd = NULL; + } + } + else + *devp = ports_get_right (bd); + return err; +} + +static io_return_t +device_write (void *d, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t bn, io_buf_ptr_t data, unsigned int count, + int *bytes_written) +{ + struct block_data *bd = d; + /* the number of pages that contain DATA. */ + int npages = (((int) data + count) - ((int) data & ~PAGE_MASK) + + PAGE_MASK) / PAGE_SIZE; + io_return_t err = D_SUCCESS; + int i; + int writes = 0; + + void write_done (int err) + { + int len = err ? 0 : count; + writes--; + if (writes == 0) + { + err = linux_to_mach_error (err); + ds_device_write_reply (reply_port, reply_port_type, err, len); + } + } + + /* the data is at the beginning of a page. */ + if ((int) data & ~PAGE_MASK) + return D_INVALID_OPERATION; + + if ((bd->mode & D_WRITE) == 0) + return D_INVALID_OPERATION; + + for (i = 0; i < npages; i++) + { + int size = PAGE_SIZE - ((int) data &~PAGE_MASK) > count ? + PAGE_SIZE - ((int) data &~PAGE_MASK) : count; + + err = block_dev_write (bd->dev, bn, data, count, write_done); + if (err) + break; + bn += count >> 9; + data += size; + count -= size; + writes++; + } + if (writes) + return MIG_NO_REPLY; + return linux_to_mach_error (err); +} + +static io_return_t +device_read (void *d, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t bn, int count, io_buf_ptr_t *data, + unsigned *bytes_read) +{ + struct block_data *bd = d; + + if ((bd->mode & D_READ) == 0) + return D_INVALID_OPERATION; + *bytes_read = 0; + return D_SUCCESS; +} + +static io_return_t +device_get_status (void *d, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t *count) +{ + struct block_data *bd = (struct block_data *) d; + return D_SUCCESS; +} + +struct device_emulation_ops linux_block_emulation_ops = +{ + NULL, + NULL, + dev_to_port, + device_open, + NULL, + device_write, + NULL, + device_read, + NULL, + NULL, + device_get_status, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +void register_block() +{ + extern void reg_dev_emul (struct device_emulation_ops *ops); + reg_dev_emul (&linux_block_emulation_ops); +} diff --git a/libmachdev/mach_glue.h b/libmachdev/mach_glue.h new file mode 100644 index 00000000..6d0870ed --- /dev/null +++ b/libmachdev/mach_glue.h @@ -0,0 +1,30 @@ +#ifndef __MACH_GLUE_H__ +#define __MACH_GLUE_H__ + +/* network */ +#include + +struct sk_buff; +struct net_device; +void skb_done_queue(struct sk_buff *skb); +struct sk_buff *skb_done_dequeue(); +void *skb_reply(struct sk_buff *skb); +int netdev_flags(struct net_device *dev); +char *netdev_addr(struct net_device *dev); +int dev_change_flags (struct net_device *dev, short flags); +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev); +struct net_device *search_netdev (char *name); +void kfree_skb (struct sk_buff *skb); +int dev_open(struct net_device *dev); +void *l4dde26_register_rx_callback(void *cb); +void skb_done_head_init(); + +/* block device */ +struct block_device; +struct block_device *open_block_dev (char *name, int part, dev_mode_t mode); +int block_dev_write (struct block_device *dev, int sectornr, + char *data, int count, void (*write_done) (int err)); + +#endif diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h index 27c488a5..cfa4b2d4 100644 --- a/libmachdev/machdev.h +++ b/libmachdev/machdev.h @@ -26,6 +26,7 @@ void ds_server(void); void mach_device_init(void); void register_net(void); +void register_block(void); void trivfs_server(void); int trivfs_init(void); diff --git a/libmachdev/net.c b/libmachdev/net.c index b21d6333..8c435b4b 100644 --- a/libmachdev/net.c +++ b/libmachdev/net.c @@ -74,6 +74,7 @@ #include "dev_hdr.h" #include "if_ether.h" #include "util.h" +#include "mach_glue.h" #define ether_header ethhdr @@ -99,22 +100,6 @@ struct skb_reply int pkglen; }; -struct sk_buff; -void skb_done_queue(struct sk_buff *skb); -struct sk_buff *skb_done_dequeue(); -void *skb_reply(struct sk_buff *skb); -int netdev_flags(struct net_device *dev); -char *netdev_addr(struct net_device *dev); -int dev_change_flags (struct net_device *dev, short flags); -int linux_pkg_xmit (char *pkg_data, int len, void *del_data, - int (*del_func) (struct sk_buff *, void *), - struct net_device *dev); -struct net_device *search_netdev (char *name); -void kfree_skb (struct sk_buff *skb); -int dev_open(struct net_device *dev); -void *l4dde26_register_rx_callback(void *cb); -void skb_done_head_init(); - static struct net_data *nd_head; /* Forward declarations. */ @@ -337,7 +322,7 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, if_init_queues (ifp); #endif - if (err = dev_open(dev) < 0) + if ((err = dev_open(dev)) < 0) { fprintf (stderr, "after dev_open: cannot open the device\n"); err = linux_to_mach_error (err); diff --git a/windhoek/Makefile b/windhoek/Makefile index 6f355bb9..803e8dba 100644 --- a/windhoek/Makefile +++ b/windhoek/Makefile @@ -27,8 +27,8 @@ SRC_C += $(IDEFILES) \ $(CDROMFILES) \ $(PARTITIONFILES) -LIBS += --whole-archive -ldde_linux26_block --no-whole-archive \ - -ldde_linux26.o -lddekit ../libmachdev/libmachdev.a \ +LIBS += --whole-archive --no-whole-archive ../libmachdev/libmachdev.a \ + -ldde_linux26_block -ldde_linux26.o -lddekit \ -lfshelp -ltrivfs -lpciaccess -lthreads -lshouldbeinlibc \ -lports -lhurd-slab diff --git a/windhoek/main.c b/windhoek/main.c index 6c3cdb89..c4e88666 100644 --- a/windhoek/main.c +++ b/windhoek/main.c @@ -66,6 +66,7 @@ int main(int argc, const char **argv) printk("| ready to rumble.... |\n"); printk("+----------------------------------------+\n"); + register_block (); mach_device_init(); trivfs_init(); -- cgit v1.2.3 From f6c6f48ca89b7867b5399a1fd24311d01b63aea1 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 5 Jun 2010 05:49:36 +0200 Subject: fix a bug in claim_irq. --- libdde_linux26/lib/src/arch/l4/irq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/lib/src/arch/l4/irq.c b/libdde_linux26/lib/src/arch/l4/irq.c index 9594b05c..20bd57f0 100644 --- a/libdde_linux26/lib/src/arch/l4/irq.c +++ b/libdde_linux26/lib/src/arch/l4/irq.c @@ -101,6 +101,7 @@ static int claim_irq(struct irqaction *action) irq_handler, (void *)irq); if (!irq->thread) { + used_irqs = irq->next; ddekit_simple_free(irq); return -EBUSY; } -- 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') 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 From 529d8041be254a2ba56543953b1daf8f1c83a204 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Mon, 9 Aug 2010 12:32:17 +0200 Subject: fake irq disable and enable. Some functions such as blk_plug_device checks whether irqs are disabled. So I need to fake irq diable in spin_lock_irq and spin_lock_irqsave. --- libdde_linux26/include/linux/spinlock.h | 10 ++++++++-- libdde_linux26/lib/src/arch/l4/cli_sti.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'libdde_linux26/lib/src/arch') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h index f038d145..6830752b 100644 --- a/libdde_linux26/include/linux/spinlock.h +++ b/libdde_linux26/include/linux/spinlock.h @@ -372,6 +372,10 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #else /* DDE_LINUX */ +unsigned long fake_local_irq_disable_flags(void); +void fake_local_irq_enable(void); +void fake_local_irq_restore(unsigned long flags); + #define spin_lock_init(l) \ do { \ ddekit_lock_init(&(l)->ddekit_lock); \ @@ -394,7 +398,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_lock(lock) spin_lock(lock) #define write_lock(lock) spin_lock(lock) -#define spin_lock_irq(lock) spin_lock(lock) +#define spin_lock_irq(lock) fake_local_irq_disable_flags(); spin_lock(lock) #define spin_lock_bh(lock) spin_lock(lock) #define read_lock_irq(lock) spin_lock_irq(lock) #define read_lock_bh(lock) spin_lock_bh(lock) @@ -411,7 +415,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_unlock(lock) spin_unlock(lock) #define write_unlock(lock) spin_unlock(lock) -#define spin_unlock_irq(lock) spin_unlock(lock) +#define spin_unlock_irq(lock) spin_unlock(lock); fake_local_irq_enable() #define spin_unlock_bh(lock) spin_unlock(lock) #define read_unlock_irq(lock) spin_unlock_irq(lock) #define read_unlock_bh(lock) spin_unlock_bh(lock) @@ -420,6 +424,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_lock_irqsave(lock, flags) \ do { \ + flags = fake_local_irq_disable_flags(); \ spin_lock(lock);\ } while (0); @@ -429,6 +434,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_unlock_irqrestore(lock, flags) \ do { \ spin_unlock(lock); \ + fake_local_irq_restore (flags); \ } while (0); #define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c index 3f5ba4cf..051f2598 100644 --- a/libdde_linux26/lib/src/arch/l4/cli_sti.c +++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c @@ -39,6 +39,21 @@ static int nested_lock(ddekit_lock_t lock) return do_lock; } +unsigned long fake_local_irq_disable_flags(void) +{ + return atomic_add_return (1, &_refcnt) - 1; +} + +void fake_local_irq_enable(void) +{ + atomic_set(&_refcnt, 0); +} + +void fake_local_irq_restore(unsigned long flags) +{ + atomic_set(&_refcnt, flags); +} + /* Store the current flags state. * * This is done by returning the current refcnt. -- cgit v1.2.3