aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/blackfin/Kconfig59
-rw-r--r--arch/blackfin/Makefile2
-rw-r--r--arch/blackfin/boot/Makefile3
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig1100
-rw-r--r--arch/blackfin/kernel/Makefile7
-rw-r--r--arch/blackfin/kernel/asm-offsets.c7
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c251
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c11
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c5
-rw-r--r--arch/blackfin/kernel/cacheinit.c66
-rw-r--r--arch/blackfin/kernel/cplbinit.c433
-rw-r--r--arch/blackfin/kernel/dma-mapping.c13
-rw-r--r--arch/blackfin/kernel/dualcore_test.c6
-rw-r--r--arch/blackfin/kernel/fixed_code.S132
-rw-r--r--arch/blackfin/kernel/flat.c55
-rw-r--r--arch/blackfin/kernel/irqchip.c2
-rw-r--r--arch/blackfin/kernel/kgdb.c421
-rw-r--r--arch/blackfin/kernel/module.c32
-rw-r--r--arch/blackfin/kernel/process.c75
-rw-r--r--arch/blackfin/kernel/ptrace.c6
-rw-r--r--arch/blackfin/kernel/setup.c368
-rw-r--r--arch/blackfin/kernel/signal.c10
-rw-r--r--arch/blackfin/kernel/sys_bfin.c8
-rw-r--r--arch/blackfin/kernel/time.c4
-rw-r--r--arch/blackfin/kernel/traps.c62
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S12
-rw-r--r--arch/blackfin/lib/strcmp.c3
-rw-r--r--arch/blackfin/lib/strcpy.c3
-rw-r--r--arch/blackfin/lib/strncmp.c3
-rw-r--r--arch/blackfin/lib/strncpy.c3
-rw-r--r--arch/blackfin/mach-bf533/Makefile4
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c14
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c8
-rw-r--r--arch/blackfin/mach-bf533/boards/generic_board.c6
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c30
-rw-r--r--arch/blackfin/mach-bf533/cpu.c3
-rw-r--r--arch/blackfin/mach-bf533/dma.c95
-rw-r--r--arch/blackfin/mach-bf533/head.S5
-rw-r--r--arch/blackfin/mach-bf533/ints-priority.c2
-rw-r--r--arch/blackfin/mach-bf537/Makefile2
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c16
-rw-r--r--arch/blackfin/mach-bf537/boards/eth_mac.c5
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c36
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c54
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c77
-rw-r--r--arch/blackfin/mach-bf537/dma.c115
-rw-r--r--arch/blackfin/mach-bf537/head.S6
-rw-r--r--arch/blackfin/mach-bf537/ints-priority.c2
-rw-r--r--arch/blackfin/mach-bf548/Kconfig316
-rw-r--r--arch/blackfin/mach-bf548/Makefile9
-rw-r--r--arch/blackfin/mach-bf548/boards/Makefile5
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c114
-rw-r--r--arch/blackfin/mach-bf548/boards/led.S172
-rw-r--r--arch/blackfin/mach-bf548/cpu.c159
-rw-r--r--arch/blackfin/mach-bf548/dma.c156
-rw-r--r--arch/blackfin/mach-bf548/gpio.c323
-rw-r--r--arch/blackfin/mach-bf548/head.S512
-rw-r--r--arch/blackfin/mach-bf548/ints-priority.c137
-rw-r--r--arch/blackfin/mach-bf561/Makefile2
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c32
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c33
-rw-r--r--arch/blackfin/mach-bf561/boards/generic_board.c6
-rw-r--r--arch/blackfin/mach-bf561/boards/tepla.c6
-rw-r--r--arch/blackfin/mach-bf561/coreb.c18
-rw-r--r--arch/blackfin/mach-bf561/dma.c131
-rw-r--r--arch/blackfin/mach-bf561/head.S6
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c2
-rw-r--r--arch/blackfin/mach-common/Makefile4
-rw-r--r--arch/blackfin/mach-common/cacheinit.S89
-rw-r--r--arch/blackfin/mach-common/cplbinfo.c13
-rw-r--r--arch/blackfin/mach-common/entry.S76
-rw-r--r--arch/blackfin/mach-common/interrupt.S8
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c13
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c405
-rw-r--r--arch/blackfin/mach-common/pm.c4
-rw-r--r--arch/blackfin/mm/blackfin_sram.c4
-rw-r--r--arch/blackfin/mm/init.c47
-rw-r--r--arch/blackfin/oprofile/common.c6
-rw-r--r--arch/blackfin/oprofile/op_model_bf533.c6
-rw-r--r--arch/blackfin/oprofile/timer_int.c3
-rw-r--r--arch/i386/Kconfig.cpu6
-rw-r--r--arch/i386/boot/Makefile48
-rw-r--r--arch/i386/boot/a20.c161
-rw-r--r--arch/i386/boot/apm.c97
-rw-r--r--arch/i386/boot/bitops.h45
-rw-r--r--arch/i386/boot/boot.h296
-rw-r--r--arch/i386/boot/bootsect.S98
-rw-r--r--arch/i386/boot/cmdline.c97
-rw-r--r--arch/i386/boot/code16gcc.h15
-rw-r--r--arch/i386/boot/compressed/Makefile7
-rw-r--r--arch/i386/boot/compressed/head.S6
-rw-r--r--arch/i386/boot/copy.S101
-rw-r--r--arch/i386/boot/cpu.c69
-rw-r--r--arch/i386/boot/cpucheck.c267
-rw-r--r--arch/i386/boot/edd.S231
-rw-r--r--arch/i386/boot/edd.c196
-rw-r--r--arch/i386/boot/header.S283
-rw-r--r--arch/i386/boot/main.c161
-rw-r--r--arch/i386/boot/mca.c43
-rw-r--r--arch/i386/boot/memory.c99
-rw-r--r--arch/i386/boot/pm.c170
-rw-r--r--arch/i386/boot/pmjump.S54
-rw-r--r--arch/i386/boot/printf.c307
-rw-r--r--arch/i386/boot/setup.S1075
-rw-r--r--arch/i386/boot/setup.ld54
-rw-r--r--arch/i386/boot/string.c52
-rw-r--r--arch/i386/boot/tools/build.c160
-rw-r--r--arch/i386/boot/tty.c112
-rw-r--r--arch/i386/boot/version.c23
-rw-r--r--arch/i386/boot/vesa.h79
-rw-r--r--arch/i386/boot/video-bios.c125
-rw-r--r--arch/i386/boot/video-vesa.c284
-rw-r--r--arch/i386/boot/video-vga.c260
-rw-r--r--arch/i386/boot/video.S2043
-rw-r--r--arch/i386/boot/video.c456
-rw-r--r--arch/i386/boot/video.h145
-rw-r--r--arch/i386/boot/voyager.c46
-rw-r--r--arch/i386/kernel/cpu/Makefile2
-rw-r--r--arch/i386/kernel/cpu/addon_cpuid_features.c50
-rw-r--r--arch/i386/kernel/cpu/common.c2
-rw-r--r--arch/i386/kernel/cpu/proc.c21
-rw-r--r--arch/i386/kernel/e820.c2
-rw-r--r--arch/i386/kernel/setup.c12
-rw-r--r--arch/i386/kernel/verify_cpu.S94
-rw-r--r--arch/mips/Kconfig21
-rw-r--r--arch/mips/au1000/common/setup.c3
-rw-r--r--arch/mips/configs/jazz_defconfig2
-rw-r--r--arch/mips/configs/qemu_defconfig2
-rw-r--r--arch/mips/configs/rm200_defconfig2
-rw-r--r--arch/mips/configs/yosemite_defconfig2
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/entry.S2
-rw-r--r--arch/mips/kernel/genex.S2
-rw-r--r--arch/mips/kernel/pcspeaker.c (renamed from arch/mips/kernel/i8253.c)0
-rw-r--r--arch/mips/kernel/r4k_switch.S7
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/lib/dump_tlb.c1
-rw-r--r--arch/mips/lib/r3k_dump_tlb.c1
-rw-r--r--arch/mips/lib/uncached.c1
-rw-r--r--arch/mips/mipssim/sim_int.c2
-rw-r--r--arch/mips/mipssim/sim_setup.c2
-rw-r--r--arch/mips/mipssim/sim_time.c1
-rw-r--r--arch/mips/pci/pci.c2
-rw-r--r--arch/mips/sibyte/swarm/time.c244
-rw-r--r--arch/mips/sni/a20r.c8
-rw-r--r--arch/mips/sni/rm200.c4
-rw-r--r--arch/mips/vr41xx/common/Makefile2
-rw-r--r--arch/mips/vr41xx/common/giu.c122
-rw-r--r--arch/mips/vr41xx/common/rtc.c117
-rw-r--r--arch/mips/vr41xx/common/siu.c120
-rw-r--r--arch/x86_64/Kconfig4
-rw-r--r--arch/x86_64/boot/Makefile136
-rw-r--r--arch/x86_64/boot/bootsect.S98
-rw-r--r--arch/x86_64/boot/compressed/Makefile9
-rw-r--r--arch/x86_64/boot/compressed/head.S6
-rw-r--r--arch/x86_64/boot/install.sh2
-rw-r--r--arch/x86_64/boot/mtools.conf.in17
-rw-r--r--arch/x86_64/boot/setup.S826
-rw-r--r--arch/x86_64/boot/tools/build.c185
-rw-r--r--arch/x86_64/kernel/Makefile2
-rw-r--r--arch/x86_64/kernel/setup.c21
-rw-r--r--arch/x86_64/kernel/verify_cpu.S22
162 files changed, 10087 insertions, 6328 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index d98bafcaca59..017defaa525b 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -71,6 +71,7 @@ config GENERIC_CALIBRATE_DELAY
71 71
72config IRQCHIP_DEMUX_GPIO 72config IRQCHIP_DEMUX_GPIO
73 bool 73 bool
74 depends on (BF53x || BF561 || BF54x)
74 default y 75 default y
75 76
76source "init/Kconfig" 77source "init/Kconfig"
@@ -114,6 +115,26 @@ config BF537
114 help 115 help
115 BF537 Processor Support. 116 BF537 Processor Support.
116 117
118config BF542
119 bool "BF542"
120 help
121 BF542 Processor Support.
122
123config BF544
124 bool "BF544"
125 help
126 BF544 Processor Support.
127
128config BF548
129 bool "BF548"
130 help
131 BF548 Processor Support.
132
133config BF549
134 bool "BF549"
135 help
136 BF549 Processor Support.
137
117config BF561 138config BF561
118 bool "BF561" 139 bool "BF561"
119 help 140 help
@@ -125,6 +146,11 @@ choice
125 prompt "Silicon Rev" 146 prompt "Silicon Rev"
126 default BF_REV_0_2 if BF537 147 default BF_REV_0_2 if BF537
127 default BF_REV_0_3 if BF533 148 default BF_REV_0_3 if BF533
149 default BF_REV_0_0 if BF549
150
151config BF_REV_0_0
152 bool "0.0"
153 depends on (BF549)
128 154
129config BF_REV_0_2 155config BF_REV_0_2
130 bool "0.2" 156 bool "0.2"
@@ -150,6 +176,16 @@ config BF_REV_NONE
150 176
151endchoice 177endchoice
152 178
179config BF53x
180 bool
181 depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
182 default y
183
184config BF54x
185 bool
186 depends on (BF542 || BF544 || BF548 || BF549)
187 default y
188
153config BFIN_DUAL_CORE 189config BFIN_DUAL_CORE
154 bool 190 bool
155 depends on (BF561) 191 depends on (BF561)
@@ -198,6 +234,12 @@ config BFIN537_BLUETECHNIX_CM
198 help 234 help
199 CM-BF537 support for EVAL- and DEV-Board. 235 CM-BF537 support for EVAL- and DEV-Board.
200 236
237config BFIN548_EZKIT
238 bool "BF548-EZKIT"
239 depends on (BF548 || BF549)
240 help
241 BFIN548-EZKIT board Support.
242
201config BFIN561_BLUETECHNIX_CM 243config BFIN561_BLUETECHNIX_CM
202 bool "Bluetechnix CM-BF561" 244 bool "Bluetechnix CM-BF561"
203 depends on (BF561) 245 depends on (BF561)
@@ -265,6 +307,7 @@ config BFIN_SHARED_FLASH_ENET
265source "arch/blackfin/mach-bf533/Kconfig" 307source "arch/blackfin/mach-bf533/Kconfig"
266source "arch/blackfin/mach-bf561/Kconfig" 308source "arch/blackfin/mach-bf561/Kconfig"
267source "arch/blackfin/mach-bf537/Kconfig" 309source "arch/blackfin/mach-bf537/Kconfig"
310source "arch/blackfin/mach-bf548/Kconfig"
268 311
269menu "Board customizations" 312menu "Board customizations"
270 313
@@ -497,7 +540,8 @@ config IP_CHECKSUM_L1
497 540
498config CACHELINE_ALIGNED_L1 541config CACHELINE_ALIGNED_L1
499 bool "Locate cacheline_aligned data to L1 Data Memory" 542 bool "Locate cacheline_aligned data to L1 Data Memory"
500 default y 543 default y if !BF54x
544 default n if BF54x
501 depends on !BF531 545 depends on !BF531
502 help 546 help
503 If enabled cacheline_anligned data is linked 547 If enabled cacheline_anligned data is linked
@@ -541,9 +585,17 @@ endchoice
541 585
542source "mm/Kconfig" 586source "mm/Kconfig"
543 587
588config LARGE_ALLOCS
589 bool "Allow allocating large blocks (> 1MB) of memory"
590 help
591 Allow the slab memory allocator to keep chains for very large
592 memory sizes - upto 32MB. You may need this if your system has
593 a lot of RAM, and you need to able to allocate very large
594 contiguous chunks. If unsure, say N.
595
544config BFIN_DMA_5XX 596config BFIN_DMA_5XX
545 bool "Enable DMA Support" 597 bool "Enable DMA Support"
546 depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561) 598 depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
547 default y 599 default y
548 help 600 help
549 DMA driver for BF5xx. 601 DMA driver for BF5xx.
@@ -686,6 +738,7 @@ config C_AMCKEN
686 738
687config C_CDPRIO 739config C_CDPRIO
688 bool "DMA has priority over core for ext. accesses" 740 bool "DMA has priority over core for ext. accesses"
741 depends on !BF54x
689 default n 742 default n
690 743
691config C_B0PEN 744config C_B0PEN
@@ -839,7 +892,7 @@ endchoice
839 892
840endmenu 893endmenu
841 894
842if (BF537 || BF533) 895if (BF537 || BF533 || BF54x)
843 896
844menu "CPU Frequency scaling" 897menu "CPU Frequency scaling"
845 898
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 6971a4418dfe..1b75672dfc8f 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -24,6 +24,8 @@ machine-$(CONFIG_BF533) := bf533
24machine-$(CONFIG_BF534) := bf537 24machine-$(CONFIG_BF534) := bf537
25machine-$(CONFIG_BF536) := bf537 25machine-$(CONFIG_BF536) := bf537
26machine-$(CONFIG_BF537) := bf537 26machine-$(CONFIG_BF537) := bf537
27machine-$(CONFIG_BF548) := bf548
28machine-$(CONFIG_BF549) := bf548
27machine-$(CONFIG_BF561) := bf561 29machine-$(CONFIG_BF561) := bf561
28MACHINE := $(machine-y) 30MACHINE := $(machine-y)
29export MACHINE 31export MACHINE
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
index 49e8098d4c21..8cd33560e817 100644
--- a/arch/blackfin/boot/Makefile
+++ b/arch/blackfin/boot/Makefile
@@ -13,7 +13,8 @@ extra-y += vmlinux.bin vmlinux.gz
13 13
14quiet_cmd_uimage = UIMAGE $@ 14quiet_cmd_uimage = UIMAGE $@
15 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ 15 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
16 -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \ 16 -C gzip -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
17 -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
17 -d $< $@ 18 -d $< $@
18 19
19$(obj)/vmlinux.bin: vmlinux FORCE 20$(obj)/vmlinux.bin: vmlinux FORCE
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
new file mode 100644
index 000000000000..ac8390fafa9c
--- /dev/null
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -0,0 +1,1100 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.21.5
4#
5# CONFIG_MMU is not set
6# CONFIG_FPU is not set
7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
9CONFIG_BLACKFIN=y
10CONFIG_ZONE_DMA=y
11CONFIG_BFIN=y
12CONFIG_SEMAPHORE_SLEEPERS=y
13CONFIG_GENERIC_FIND_NEXT_BIT=y
14CONFIG_GENERIC_HWEIGHT=y
15CONFIG_GENERIC_HARDIRQS=y
16CONFIG_GENERIC_IRQ_PROBE=y
17# CONFIG_GENERIC_TIME is not set
18CONFIG_GENERIC_CALIBRATE_DELAY=y
19CONFIG_FORCE_MAX_ZONEORDER=14
20CONFIG_IRQCHIP_DEMUX_GPIO=y
21CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
22
23#
24# Code maturity level options
25#
26CONFIG_EXPERIMENTAL=y
27CONFIG_BROKEN_ON_SMP=y
28CONFIG_INIT_ENV_ARG_LIMIT=32
29
30#
31# General setup
32#
33CONFIG_LOCALVERSION=""
34CONFIG_LOCALVERSION_AUTO=y
35CONFIG_SYSVIPC=y
36# CONFIG_IPC_NS is not set
37CONFIG_SYSVIPC_SYSCTL=y
38# CONFIG_POSIX_MQUEUE is not set
39# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set
41# CONFIG_UTS_NS is not set
42# CONFIG_AUDIT is not set
43# CONFIG_IKCONFIG is not set
44CONFIG_SYSFS_DEPRECATED=y
45# CONFIG_RELAY is not set
46CONFIG_BLK_DEV_INITRD=y
47CONFIG_INITRAMFS_SOURCE=""
48# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
49CONFIG_SYSCTL=y
50CONFIG_EMBEDDED=y
51CONFIG_UID16=y
52CONFIG_SYSCTL_SYSCALL=y
53CONFIG_KALLSYMS=y
54# CONFIG_KALLSYMS_ALL is not set
55# CONFIG_KALLSYMS_EXTRA_PASS is not set
56CONFIG_HOTPLUG=y
57CONFIG_PRINTK=y
58CONFIG_BUG=y
59CONFIG_ELF_CORE=y
60CONFIG_BASE_FULL=y
61CONFIG_FUTEX=y
62CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
63# CONFIG_NP2 is not set
64CONFIG_SLAB=y
65CONFIG_VM_EVENT_COUNTERS=y
66CONFIG_RT_MUTEXES=y
67CONFIG_TINY_SHMEM=y
68CONFIG_BASE_SMALL=0
69# CONFIG_SLOB is not set
70
71#
72# Loadable module support
73#
74CONFIG_MODULES=y
75CONFIG_MODULE_UNLOAD=y
76# CONFIG_MODULE_FORCE_UNLOAD is not set
77# CONFIG_MODVERSIONS is not set
78# CONFIG_MODULE_SRCVERSION_ALL is not set
79CONFIG_KMOD=y
80
81#
82# Block layer
83#
84CONFIG_BLOCK=y
85# CONFIG_LBD is not set
86# CONFIG_BLK_DEV_IO_TRACE is not set
87# CONFIG_LSF is not set
88
89#
90# IO Schedulers
91#
92CONFIG_IOSCHED_NOOP=y
93CONFIG_IOSCHED_AS=y
94# CONFIG_IOSCHED_DEADLINE is not set
95CONFIG_IOSCHED_CFQ=y
96CONFIG_DEFAULT_AS=y
97# CONFIG_DEFAULT_DEADLINE is not set
98# CONFIG_DEFAULT_CFQ is not set
99# CONFIG_DEFAULT_NOOP is not set
100CONFIG_DEFAULT_IOSCHED="anticipatory"
101# CONFIG_PREEMPT_NONE is not set
102CONFIG_PREEMPT_VOLUNTARY=y
103# CONFIG_PREEMPT is not set
104
105#
106# Blackfin Processor Options
107#
108
109#
110# Processor and Board Settings
111#
112# CONFIG_BF531 is not set
113# CONFIG_BF532 is not set
114# CONFIG_BF533 is not set
115# CONFIG_BF534 is not set
116# CONFIG_BF536 is not set
117# CONFIG_BF537 is not set
118# CONFIG_BF542 is not set
119# CONFIG_BF544 is not set
120# CONFIG_BF548 is not set
121CONFIG_BF549=y
122# CONFIG_BF561 is not set
123CONFIG_BF_REV_0_0=y
124# CONFIG_BF_REV_0_2 is not set
125# CONFIG_BF_REV_0_3 is not set
126# CONFIG_BF_REV_0_4 is not set
127# CONFIG_BF_REV_0_5 is not set
128# CONFIG_BF_REV_ANY is not set
129# CONFIG_BF_REV_NONE is not set
130CONFIG_BF54x=y
131CONFIG_BFIN_SINGLE_CORE=y
132# CONFIG_BFIN533_EZKIT is not set
133# CONFIG_BFIN533_STAMP is not set
134# CONFIG_BFIN537_STAMP is not set
135# CONFIG_BFIN533_BLUETECHNIX_CM is not set
136# CONFIG_BFIN537_BLUETECHNIX_CM is not set
137CONFIG_BFIN548_EZKIT=y
138# CONFIG_BFIN561_BLUETECHNIX_CM is not set
139# CONFIG_BFIN561_EZKIT is not set
140# CONFIG_BFIN561_TEPLA is not set
141# CONFIG_PNAV10 is not set
142# CONFIG_GENERIC_BOARD is not set
143CONFIG_IRQ_PLL_WAKEUP=7
144CONFIG_IRQ_TIMER0=11
145CONFIG_IRQ_TIMER1=11
146CONFIG_IRQ_TIMER2=11
147CONFIG_IRQ_TIMER3=11
148CONFIG_IRQ_TIMER4=11
149CONFIG_IRQ_TIMER5=11
150CONFIG_IRQ_TIMER6=11
151CONFIG_IRQ_TIMER7=11
152CONFIG_IRQ_TIMER8=11
153CONFIG_IRQ_TIMER9=11
154CONFIG_IRQ_TIMER10=11
155CONFIG_IRQ_RTC=8
156CONFIG_IRQ_SPORT0_RX=9
157CONFIG_IRQ_SPORT0_TX=9
158CONFIG_IRQ_SPORT1_RX=9
159CONFIG_IRQ_SPORT1_TX=9
160CONFIG_IRQ_UART0_RX=10
161CONFIG_IRQ_UART0_TX=10
162CONFIG_IRQ_UART1_RX=10
163CONFIG_IRQ_UART1_TX=10
164
165#
166# BF548 Specific Configuration
167#
168
169#
170# Interrupt Priority Assignment
171#
172
173#
174# Priority
175#
176CONFIG_IRQ_DMAC0_ERR=7
177CONFIG_IRQ_EPPI0_ERR=7
178CONFIG_IRQ_SPORT0_ERR=7
179CONFIG_IRQ_SPORT1_ERR=7
180CONFIG_IRQ_SPI0_ERR=7
181CONFIG_IRQ_UART0_ERR=7
182CONFIG_IRQ_EPPI0=8
183CONFIG_IRQ_SPI0=10
184CONFIG_IRQ_PINT0=12
185CONFIG_IRQ_PINT1=12
186CONFIG_IRQ_MDMAS0=13
187CONFIG_IRQ_MDMAS1=13
188CONFIG_IRQ_WATCHDOG=13
189CONFIG_IRQ_DMAC1_ERR=7
190CONFIG_IRQ_SPORT2_ERR=7
191CONFIG_IRQ_SPORT3_ERR=7
192CONFIG_IRQ_MXVR_DATA=7
193CONFIG_IRQ_SPI1_ERR=7
194CONFIG_IRQ_SPI2_ERR=7
195CONFIG_IRQ_UART1_ERR=7
196CONFIG_IRQ_UART2_ERR=7
197CONFIG_IRQ_CAN0_ERR=7
198CONFIG_IRQ_SPORT2_RX=9
199CONFIG_IRQ_SPORT2_TX=9
200CONFIG_IRQ_SPORT3_RX=9
201CONFIG_IRQ_SPORT3_TX=9
202CONFIG_IRQ_EPPI1=9
203CONFIG_IRQ_EPPI2=9
204CONFIG_IRQ_SPI1=10
205CONFIG_IRQ_SPI2=10
206CONFIG_IRQ_ATAPI_RX=10
207CONFIG_IRQ_ATAPI_TX=10
208CONFIG_IRQ_TWI0=11
209CONFIG_IRQ_TWI1=11
210CONFIG_IRQ_CAN0_RX=11
211CONFIG_IRQ_CAN0_TX=11
212CONFIG_IRQ_MDMAS2=13
213CONFIG_IRQ_MDMAS3=13
214CONFIG_IRQ_MXVR_ERR=11
215CONFIG_IRQ_MXVR_MSG=11
216CONFIG_IRQ_MXVR_PKT=11
217CONFIG_IRQ_EPPI1_ERR=7
218CONFIG_IRQ_EPPI2_ERR=7
219CONFIG_IRQ_UART3_ERR=7
220CONFIG_IRQ_HOST_ERR=7
221CONFIG_IRQ_PIXC_ERR=7
222CONFIG_IRQ_NFC_ERR=7
223CONFIG_IRQ_ATAPI_ERR=7
224CONFIG_IRQ_CAN1_ERR=7
225CONFIG_IRQ_HS_DMA_ERR=7
226CONFIG_IRQ_PIXC_IN0=8
227CONFIG_IRQ_PIXC_IN1=8
228CONFIG_IRQ_PIXC_OUT=8
229CONFIG_IRQ_SDH=8
230CONFIG_IRQ_CNT=8
231CONFIG_IRQ_KEY=8
232CONFIG_IRQ_CAN1_RX=11
233CONFIG_IRQ_CAN1_TX=11
234CONFIG_IRQ_SDH_MASK0=11
235CONFIG_IRQ_SDH_MASK1=11
236CONFIG_IRQ_USB_INT0=11
237CONFIG_IRQ_USB_INT1=11
238CONFIG_IRQ_USB_INT2=11
239CONFIG_IRQ_USB_DMA=11
240CONFIG_IRQ_OTPSEC=11
241CONFIG_IRQ_PINT2=11
242CONFIG_IRQ_PINT3=11
243
244#
245# Board customizations
246#
247# CONFIG_CMDLINE_BOOL is not set
248
249#
250# Board Setup
251#
252CONFIG_CLKIN_HZ=25000000
253CONFIG_MEM_SIZE=64
254CONFIG_MEM_ADD_WIDTH=10
255CONFIG_BOOT_LOAD=0x1000
256
257#
258# Blackfin Kernel Optimizations
259#
260
261#
262# Timer Tick
263#
264# CONFIG_HZ_100 is not set
265CONFIG_HZ_250=y
266# CONFIG_HZ_300 is not set
267# CONFIG_HZ_1000 is not set
268CONFIG_HZ=250
269
270#
271# Memory Optimizations
272#
273CONFIG_I_ENTRY_L1=y
274CONFIG_EXCPT_IRQ_SYSC_L1=y
275CONFIG_DO_IRQ_L1=y
276CONFIG_CORE_TIMER_IRQ_L1=y
277CONFIG_IDLE_L1=y
278CONFIG_SCHEDULE_L1=y
279CONFIG_ARITHMETIC_OPS_L1=y
280CONFIG_ACCESS_OK_L1=y
281CONFIG_MEMSET_L1=y
282CONFIG_MEMCPY_L1=y
283CONFIG_SYS_BFIN_SPINLOCK_L1=y
284# CONFIG_IP_CHECKSUM_L1 is not set
285CONFIG_CACHELINE_ALIGNED_L1=y
286# CONFIG_SYSCALL_TAB_L1 is not set
287# CONFIG_CPLB_SWITCH_TAB_L1 is not set
288CONFIG_RAMKERNEL=y
289# CONFIG_ROMKERNEL is not set
290CONFIG_SELECT_MEMORY_MODEL=y
291CONFIG_FLATMEM_MANUAL=y
292# CONFIG_DISCONTIGMEM_MANUAL is not set
293# CONFIG_SPARSEMEM_MANUAL is not set
294CONFIG_FLATMEM=y
295CONFIG_FLAT_NODE_MEM_MAP=y
296# CONFIG_SPARSEMEM_STATIC is not set
297CONFIG_SPLIT_PTLOCK_CPUS=4
298# CONFIG_RESOURCES_64BIT is not set
299CONFIG_ZONE_DMA_FLAG=1
300CONFIG_LARGE_ALLOCS=y
301CONFIG_BFIN_DMA_5XX=y
302# CONFIG_DMA_UNCACHED_2M is not set
303CONFIG_DMA_UNCACHED_1M=y
304# CONFIG_DMA_UNCACHED_NONE is not set
305
306#
307# Cache Support
308#
309CONFIG_BLKFIN_CACHE=y
310CONFIG_BLKFIN_DCACHE=y
311# CONFIG_BLKFIN_DCACHE_BANKA is not set
312# CONFIG_BLKFIN_CACHE_LOCK is not set
313# CONFIG_BLKFIN_WB is not set
314CONFIG_BLKFIN_WT=y
315CONFIG_L1_MAX_PIECE=16
316
317#
318# Clock Settings
319#
320# CONFIG_BFIN_KERNEL_CLOCK is not set
321
322#
323# Asynchonous Memory Configuration
324#
325
326#
327# EBIU_AMBCTL Global Control
328#
329CONFIG_C_AMCKEN=y
330CONFIG_C_CDPRIO=y
331# CONFIG_C_AMBEN is not set
332# CONFIG_C_AMBEN_B0 is not set
333# CONFIG_C_AMBEN_B0_B1 is not set
334# CONFIG_C_AMBEN_B0_B1_B2 is not set
335CONFIG_C_AMBEN_ALL=y
336
337#
338# EBIU_AMBCTL Control
339#
340CONFIG_BANK_0=0x7BB0
341CONFIG_BANK_1=0x7BB0
342CONFIG_BANK_2=0x7BB0
343CONFIG_BANK_3=0x99B3
344
345#
346# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
347#
348# CONFIG_PCI is not set
349
350#
351# PCCARD (PCMCIA/CardBus) support
352#
353# CONFIG_PCCARD is not set
354
355#
356# PCI Hotplug Support
357#
358
359#
360# Executable file formats
361#
362CONFIG_BINFMT_ELF_FDPIC=y
363CONFIG_BINFMT_FLAT=y
364CONFIG_BINFMT_ZFLAT=y
365# CONFIG_BINFMT_SHARED_FLAT is not set
366# CONFIG_BINFMT_MISC is not set
367
368#
369# Power management options
370#
371# CONFIG_PM is not set
372
373#
374# CPU Frequency scaling
375#
376# CONFIG_CPU_FREQ is not set
377
378#
379# Networking
380#
381CONFIG_NET=y
382
383#
384# Networking options
385#
386# CONFIG_NETDEBUG is not set
387CONFIG_PACKET=y
388# CONFIG_PACKET_MMAP is not set
389CONFIG_UNIX=y
390CONFIG_XFRM=y
391# CONFIG_XFRM_USER is not set
392# CONFIG_XFRM_SUB_POLICY is not set
393# CONFIG_XFRM_MIGRATE is not set
394# CONFIG_NET_KEY is not set
395CONFIG_INET=y
396# CONFIG_IP_MULTICAST is not set
397# CONFIG_IP_ADVANCED_ROUTER is not set
398CONFIG_IP_FIB_HASH=y
399CONFIG_IP_PNP=y
400# CONFIG_IP_PNP_DHCP is not set
401# CONFIG_IP_PNP_BOOTP is not set
402# CONFIG_IP_PNP_RARP is not set
403# CONFIG_NET_IPIP is not set
404# CONFIG_NET_IPGRE is not set
405# CONFIG_ARPD is not set
406CONFIG_SYN_COOKIES=y
407# CONFIG_INET_AH is not set
408# CONFIG_INET_ESP is not set
409# CONFIG_INET_IPCOMP is not set
410# CONFIG_INET_XFRM_TUNNEL is not set
411# CONFIG_INET_TUNNEL is not set
412CONFIG_INET_XFRM_MODE_TRANSPORT=y
413CONFIG_INET_XFRM_MODE_TUNNEL=y
414CONFIG_INET_XFRM_MODE_BEET=y
415CONFIG_INET_DIAG=y
416CONFIG_INET_TCP_DIAG=y
417# CONFIG_TCP_CONG_ADVANCED is not set
418CONFIG_TCP_CONG_CUBIC=y
419CONFIG_DEFAULT_TCP_CONG="cubic"
420# CONFIG_TCP_MD5SIG is not set
421# CONFIG_IPV6 is not set
422# CONFIG_INET6_XFRM_TUNNEL is not set
423# CONFIG_INET6_TUNNEL is not set
424# CONFIG_NETLABEL is not set
425# CONFIG_NETWORK_SECMARK is not set
426# CONFIG_NETFILTER is not set
427
428#
429# DCCP Configuration (EXPERIMENTAL)
430#
431# CONFIG_IP_DCCP is not set
432
433#
434# SCTP Configuration (EXPERIMENTAL)
435#
436# CONFIG_IP_SCTP is not set
437
438#
439# TIPC Configuration (EXPERIMENTAL)
440#
441# CONFIG_TIPC is not set
442# CONFIG_ATM is not set
443# CONFIG_BRIDGE is not set
444# CONFIG_VLAN_8021Q is not set
445# CONFIG_DECNET is not set
446# CONFIG_LLC2 is not set
447# CONFIG_IPX is not set
448# CONFIG_ATALK is not set
449# CONFIG_X25 is not set
450# CONFIG_LAPB is not set
451# CONFIG_ECONET is not set
452# CONFIG_WAN_ROUTER is not set
453
454#
455# QoS and/or fair queueing
456#
457# CONFIG_NET_SCHED is not set
458
459#
460# Network testing
461#
462# CONFIG_NET_PKTGEN is not set
463# CONFIG_HAMRADIO is not set
464# CONFIG_IRDA is not set
465# CONFIG_BT is not set
466# CONFIG_IEEE80211 is not set
467
468#
469# Device Drivers
470#
471
472#
473# Generic Driver Options
474#
475CONFIG_STANDALONE=y
476CONFIG_PREVENT_FIRMWARE_BUILD=y
477# CONFIG_FW_LOADER is not set
478# CONFIG_DEBUG_DRIVER is not set
479# CONFIG_DEBUG_DEVRES is not set
480# CONFIG_SYS_HYPERVISOR is not set
481
482#
483# Connector - unified userspace <-> kernelspace linker
484#
485# CONFIG_CONNECTOR is not set
486
487#
488# Memory Technology Devices (MTD)
489#
490CONFIG_MTD=y
491# CONFIG_MTD_DEBUG is not set
492# CONFIG_MTD_CONCAT is not set
493CONFIG_MTD_PARTITIONS=y
494# CONFIG_MTD_REDBOOT_PARTS is not set
495# CONFIG_MTD_CMDLINE_PARTS is not set
496
497#
498# User Modules And Translation Layers
499#
500# CONFIG_MTD_CHAR is not set
501CONFIG_MTD_BLKDEVS=y
502CONFIG_MTD_BLOCK=y
503# CONFIG_FTL is not set
504# CONFIG_NFTL is not set
505# CONFIG_INFTL is not set
506# CONFIG_RFD_FTL is not set
507# CONFIG_SSFDC is not set
508
509#
510# RAM/ROM/Flash chip drivers
511#
512# CONFIG_MTD_CFI is not set
513# CONFIG_MTD_JEDECPROBE is not set
514CONFIG_MTD_MAP_BANK_WIDTH_1=y
515CONFIG_MTD_MAP_BANK_WIDTH_2=y
516CONFIG_MTD_MAP_BANK_WIDTH_4=y
517# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
518# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
519# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
520CONFIG_MTD_CFI_I1=y
521CONFIG_MTD_CFI_I2=y
522# CONFIG_MTD_CFI_I4 is not set
523# CONFIG_MTD_CFI_I8 is not set
524CONFIG_MTD_RAM=y
525# CONFIG_MTD_ROM is not set
526# CONFIG_MTD_ABSENT is not set
527# CONFIG_MTD_OBSOLETE_CHIPS is not set
528
529#
530# Mapping drivers for chip access
531#
532CONFIG_MTD_COMPLEX_MAPPINGS=y
533# CONFIG_MTD_BF5xx is not set
534CONFIG_MTD_UCLINUX=y
535# CONFIG_MTD_PLATRAM is not set
536
537#
538# Self-contained MTD device drivers
539#
540# CONFIG_MTD_SLRAM is not set
541# CONFIG_MTD_PHRAM is not set
542# CONFIG_MTD_MTDRAM is not set
543# CONFIG_MTD_BLOCK2MTD is not set
544
545#
546# Disk-On-Chip Device Drivers
547#
548# CONFIG_MTD_DOC2000 is not set
549# CONFIG_MTD_DOC2001 is not set
550# CONFIG_MTD_DOC2001PLUS is not set
551
552#
553# NAND Flash Device Drivers
554#
555# CONFIG_MTD_NAND is not set
556
557#
558# OneNAND Flash Device Drivers
559#
560# CONFIG_MTD_ONENAND is not set
561
562#
563# Parallel port support
564#
565# CONFIG_PARPORT is not set
566
567#
568# Plug and Play support
569#
570# CONFIG_PNPACPI is not set
571
572#
573# Block devices
574#
575# CONFIG_BLK_DEV_COW_COMMON is not set
576# CONFIG_BLK_DEV_LOOP is not set
577# CONFIG_BLK_DEV_NBD is not set
578CONFIG_BLK_DEV_RAM=y
579CONFIG_BLK_DEV_RAM_COUNT=16
580CONFIG_BLK_DEV_RAM_SIZE=4096
581CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
582# CONFIG_CDROM_PKTCDVD is not set
583# CONFIG_ATA_OVER_ETH is not set
584
585#
586# Misc devices
587#
588
589#
590# ATA/ATAPI/MFM/RLL support
591#
592# CONFIG_IDE is not set
593
594#
595# SCSI device support
596#
597# CONFIG_RAID_ATTRS is not set
598# CONFIG_SCSI is not set
599# CONFIG_SCSI_NETLINK is not set
600
601#
602# Serial ATA (prod) and Parallel ATA (experimental) drivers
603#
604# CONFIG_ATA is not set
605
606#
607# Multi-device support (RAID and LVM)
608#
609# CONFIG_MD is not set
610
611#
612# Fusion MPT device support
613#
614# CONFIG_FUSION is not set
615
616#
617# IEEE 1394 (FireWire) support
618#
619
620#
621# I2O device support
622#
623
624#
625# Network device support
626#
627CONFIG_NETDEVICES=y
628# CONFIG_DUMMY is not set
629# CONFIG_BONDING is not set
630# CONFIG_EQUALIZER is not set
631# CONFIG_TUN is not set
632
633#
634# PHY device support
635#
636# CONFIG_PHYLIB is not set
637
638#
639# Ethernet (10 or 100Mbit)
640#
641CONFIG_NET_ETHERNET=y
642CONFIG_MII=y
643# CONFIG_SMC91X is not set
644# CONFIG_SMSC911X is not set
645
646#
647# Ethernet (1000 Mbit)
648#
649
650#
651# Ethernet (10000 Mbit)
652#
653
654#
655# Token Ring devices
656#
657
658#
659# Wireless LAN (non-hamradio)
660#
661# CONFIG_NET_RADIO is not set
662
663#
664# Wan interfaces
665#
666# CONFIG_WAN is not set
667# CONFIG_PPP is not set
668# CONFIG_SLIP is not set
669# CONFIG_SHAPER is not set
670# CONFIG_NETCONSOLE is not set
671# CONFIG_NETPOLL is not set
672# CONFIG_NET_POLL_CONTROLLER is not set
673
674#
675# ISDN subsystem
676#
677# CONFIG_ISDN is not set
678
679#
680# Telephony Support
681#
682# CONFIG_PHONE is not set
683
684#
685# Input device support
686#
687CONFIG_INPUT=y
688# CONFIG_INPUT_FF_MEMLESS is not set
689
690#
691# Userland interfaces
692#
693# CONFIG_INPUT_MOUSEDEV is not set
694# CONFIG_INPUT_JOYDEV is not set
695# CONFIG_INPUT_TSDEV is not set
696# CONFIG_INPUT_EVDEV is not set
697# CONFIG_INPUT_EVBUG is not set
698
699#
700# Input Device Drivers
701#
702# CONFIG_INPUT_KEYBOARD is not set
703# CONFIG_INPUT_MOUSE is not set
704# CONFIG_INPUT_JOYSTICK is not set
705# CONFIG_INPUT_TOUCHSCREEN is not set
706CONFIG_INPUT_MISC=y
707# CONFIG_INPUT_UINPUT is not set
708# CONFIG_BF53X_PFBUTTONS is not set
709
710#
711# Hardware I/O ports
712#
713# CONFIG_SERIO is not set
714# CONFIG_GAMEPORT is not set
715
716#
717# Character devices
718#
719# CONFIG_AD9960 is not set
720# CONFIG_SPI_ADC_BF533 is not set
721# CONFIG_BF5xx_PFLAGS is not set
722# CONFIG_BF5xx_PPIFCD is not set
723# CONFIG_BF5xx_TIMERS is not set
724# CONFIG_BF5xx_PPI is not set
725# CONFIG_BFIN_SPORT is not set
726# CONFIG_BFIN_TIMER_LATENCY is not set
727# CONFIG_BF5xx_FBDMA is not set
728# CONFIG_VT is not set
729# CONFIG_SERIAL_NONSTANDARD is not set
730
731#
732# Serial drivers
733#
734# CONFIG_SERIAL_8250 is not set
735
736#
737# Non-8250 serial port support
738#
739CONFIG_SERIAL_BFIN=y
740CONFIG_SERIAL_BFIN_CONSOLE=y
741# CONFIG_SERIAL_BFIN_DMA is not set
742CONFIG_SERIAL_BFIN_PIO=y
743# CONFIG_SERIAL_BFIN_UART0 is not set
744CONFIG_SERIAL_BFIN_UART1=y
745# CONFIG_BFIN_UART1_CTSRTS is not set
746# CONFIG_SERIAL_BFIN_UART2 is not set
747# CONFIG_SERIAL_BFIN_UART3 is not set
748CONFIG_SERIAL_CORE=y
749CONFIG_SERIAL_CORE_CONSOLE=y
750# CONFIG_SERIAL_BFIN_SPORT is not set
751CONFIG_UNIX98_PTYS=y
752# CONFIG_LEGACY_PTYS is not set
753
754#
755# CAN, the car bus and industrial fieldbus
756#
757# CONFIG_CAN4LINUX is not set
758
759#
760# IPMI
761#
762# CONFIG_IPMI_HANDLER is not set
763
764#
765# Watchdog Cards
766#
767# CONFIG_WATCHDOG is not set
768CONFIG_HW_RANDOM=y
769# CONFIG_GEN_RTC is not set
770# CONFIG_DTLK is not set
771# CONFIG_R3964 is not set
772# CONFIG_RAW_DRIVER is not set
773
774#
775# TPM devices
776#
777# CONFIG_TCG_TPM is not set
778
779#
780# I2C support
781#
782# CONFIG_I2C is not set
783
784#
785# SPI support
786#
787# CONFIG_SPI is not set
788# CONFIG_SPI_MASTER is not set
789
790#
791# Dallas's 1-wire bus
792#
793# CONFIG_W1 is not set
794
795#
796# Hardware Monitoring support
797#
798CONFIG_HWMON=y
799# CONFIG_HWMON_VID is not set
800# CONFIG_SENSORS_ABITUGURU is not set
801# CONFIG_SENSORS_F71805F is not set
802# CONFIG_SENSORS_PC87427 is not set
803# CONFIG_SENSORS_VT1211 is not set
804# CONFIG_HWMON_DEBUG_CHIP is not set
805
806#
807# Multifunction device drivers
808#
809# CONFIG_MFD_SM501 is not set
810
811#
812# Multimedia devices
813#
814# CONFIG_VIDEO_DEV is not set
815
816#
817# Digital Video Broadcasting Devices
818#
819# CONFIG_DVB is not set
820
821#
822# Graphics support
823#
824# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
825# CONFIG_FB is not set
826
827#
828# Sound
829#
830# CONFIG_SOUND is not set
831
832#
833# HID Devices
834#
835CONFIG_HID=y
836# CONFIG_HID_DEBUG is not set
837
838#
839# USB support
840#
841CONFIG_USB_ARCH_HAS_HCD=y
842# CONFIG_USB_ARCH_HAS_OHCI is not set
843# CONFIG_USB_ARCH_HAS_EHCI is not set
844# CONFIG_USB is not set
845
846#
847# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
848#
849
850#
851# USB Gadget Support
852#
853# CONFIG_USB_GADGET is not set
854
855#
856# MMC/SD Card support
857#
858# CONFIG_MMC is not set
859
860#
861# LED devices
862#
863# CONFIG_NEW_LEDS is not set
864
865#
866# LED drivers
867#
868
869#
870# LED Triggers
871#
872
873#
874# InfiniBand support
875#
876
877#
878# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
879#
880
881#
882# Real Time Clock
883#
884CONFIG_RTC_LIB=y
885CONFIG_RTC_CLASS=y
886CONFIG_RTC_HCTOSYS=y
887CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
888# CONFIG_RTC_DEBUG is not set
889
890#
891# RTC interfaces
892#
893CONFIG_RTC_INTF_SYSFS=y
894CONFIG_RTC_INTF_PROC=y
895CONFIG_RTC_INTF_DEV=y
896# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
897
898#
899# RTC drivers
900#
901# CONFIG_RTC_DRV_DS1553 is not set
902# CONFIG_RTC_DRV_DS1742 is not set
903# CONFIG_RTC_DRV_M48T86 is not set
904# CONFIG_RTC_DRV_TEST is not set
905# CONFIG_RTC_DRV_V3020 is not set
906CONFIG_RTC_DRV_BFIN=y
907
908#
909# DMA Engine support
910#
911# CONFIG_DMA_ENGINE is not set
912
913#
914# DMA Clients
915#
916
917#
918# DMA Devices
919#
920
921#
922# Auxiliary Display support
923#
924
925#
926# Virtualization
927#
928
929#
930# PBX support
931#
932# CONFIG_PBX is not set
933
934#
935# File systems
936#
937CONFIG_EXT2_FS=y
938CONFIG_EXT2_FS_XATTR=y
939# CONFIG_EXT2_FS_POSIX_ACL is not set
940# CONFIG_EXT2_FS_SECURITY is not set
941# CONFIG_EXT3_FS is not set
942# CONFIG_EXT4DEV_FS is not set
943CONFIG_FS_MBCACHE=y
944# CONFIG_REISERFS_FS is not set
945# CONFIG_JFS_FS is not set
946# CONFIG_FS_POSIX_ACL is not set
947# CONFIG_XFS_FS is not set
948# CONFIG_GFS2_FS is not set
949# CONFIG_OCFS2_FS is not set
950# CONFIG_MINIX_FS is not set
951# CONFIG_ROMFS_FS is not set
952CONFIG_INOTIFY=y
953CONFIG_INOTIFY_USER=y
954# CONFIG_QUOTA is not set
955CONFIG_DNOTIFY=y
956# CONFIG_AUTOFS_FS is not set
957# CONFIG_AUTOFS4_FS is not set
958# CONFIG_FUSE_FS is not set
959
960#
961# CD-ROM/DVD Filesystems
962#
963# CONFIG_ISO9660_FS is not set
964# CONFIG_UDF_FS is not set
965
966#
967# DOS/FAT/NT Filesystems
968#
969# CONFIG_MSDOS_FS is not set
970# CONFIG_VFAT_FS is not set
971# CONFIG_NTFS_FS is not set
972
973#
974# Pseudo filesystems
975#
976CONFIG_PROC_FS=y
977CONFIG_PROC_SYSCTL=y
978CONFIG_SYSFS=y
979# CONFIG_TMPFS is not set
980# CONFIG_HUGETLB_PAGE is not set
981CONFIG_RAMFS=y
982# CONFIG_CONFIGFS_FS is not set
983
984#
985# Miscellaneous filesystems
986#
987# CONFIG_ADFS_FS is not set
988# CONFIG_AFFS_FS is not set
989# CONFIG_HFS_FS is not set
990# CONFIG_HFSPLUS_FS is not set
991# CONFIG_BEFS_FS is not set
992# CONFIG_BFS_FS is not set
993# CONFIG_EFS_FS is not set
994# CONFIG_YAFFS_FS is not set
995# CONFIG_JFFS2_FS is not set
996# CONFIG_CRAMFS is not set
997# CONFIG_VXFS_FS is not set
998# CONFIG_HPFS_FS is not set
999# CONFIG_QNX4FS_FS is not set
1000# CONFIG_SYSV_FS is not set
1001# CONFIG_UFS_FS is not set
1002
1003#
1004# Network File Systems
1005#
1006# CONFIG_NFS_FS is not set
1007# CONFIG_NFSD is not set
1008# CONFIG_SMB_FS is not set
1009# CONFIG_CIFS is not set
1010# CONFIG_NCP_FS is not set
1011# CONFIG_CODA_FS is not set
1012# CONFIG_AFS_FS is not set
1013# CONFIG_9P_FS is not set
1014
1015#
1016# Partition Types
1017#
1018# CONFIG_PARTITION_ADVANCED is not set
1019CONFIG_MSDOS_PARTITION=y
1020
1021#
1022# Native Language Support
1023#
1024# CONFIG_NLS is not set
1025
1026#
1027# Distributed Lock Manager
1028#
1029# CONFIG_DLM is not set
1030
1031#
1032# Profiling support
1033#
1034# CONFIG_PROFILING is not set
1035
1036#
1037# Kernel hacking
1038#
1039# CONFIG_PRINTK_TIME is not set
1040CONFIG_ENABLE_MUST_CHECK=y
1041CONFIG_MAGIC_SYSRQ=y
1042# CONFIG_UNUSED_SYMBOLS is not set
1043# CONFIG_DEBUG_FS is not set
1044# CONFIG_HEADERS_CHECK is not set
1045CONFIG_DEBUG_KERNEL=y
1046# CONFIG_DEBUG_SHIRQ is not set
1047CONFIG_LOG_BUF_SHIFT=14
1048CONFIG_DETECT_SOFTLOCKUP=y
1049# CONFIG_SCHEDSTATS is not set
1050# CONFIG_TIMER_STATS is not set
1051# CONFIG_DEBUG_SLAB is not set
1052# CONFIG_DEBUG_RT_MUTEXES is not set
1053# CONFIG_RT_MUTEX_TESTER is not set
1054# CONFIG_DEBUG_SPINLOCK is not set
1055# CONFIG_DEBUG_MUTEXES is not set
1056# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1057# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1058# CONFIG_DEBUG_KOBJECT is not set
1059# CONFIG_DEBUG_BUGVERBOSE is not set
1060CONFIG_DEBUG_INFO=y
1061# CONFIG_DEBUG_VM is not set
1062# CONFIG_DEBUG_LIST is not set
1063CONFIG_FRAME_POINTER=y
1064CONFIG_FORCED_INLINING=y
1065# CONFIG_RCU_TORTURE_TEST is not set
1066# CONFIG_FAULT_INJECTION is not set
1067CONFIG_DEBUG_HWERR=y
1068# CONFIG_DEBUG_ICACHE_CHECK is not set
1069# CONFIG_DEBUG_KERNEL_START is not set
1070# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
1071CONFIG_DEBUG_HUNT_FOR_ZERO=y
1072# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
1073CONFIG_CPLB_INFO=y
1074CONFIG_ACCESS_CHECK=y
1075
1076#
1077# Security options
1078#
1079# CONFIG_KEYS is not set
1080CONFIG_SECURITY=y
1081# CONFIG_SECURITY_NETWORK is not set
1082CONFIG_SECURITY_CAPABILITIES=y
1083
1084#
1085# Cryptographic options
1086#
1087# CONFIG_CRYPTO is not set
1088
1089#
1090# Library routines
1091#
1092CONFIG_BITREVERSE=y
1093# CONFIG_CRC_CCITT is not set
1094# CONFIG_CRC16 is not set
1095CONFIG_CRC32=y
1096# CONFIG_LIBCRC32C is not set
1097CONFIG_ZLIB_INFLATE=y
1098CONFIG_PLIST=y
1099CONFIG_HAS_IOMEM=y
1100CONFIG_HAS_IOPORT=y
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index f3b7d2f9d49c..f429ebc3a961 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -6,9 +6,12 @@ extra-y := init_task.o vmlinux.lds
6 6
7obj-y := \ 7obj-y := \
8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ 8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
9 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \ 9 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
10 flat.o 10 fixed_code.o cplbinit.o cacheinit.o
11 11
12obj-$(CONFIG_BF53x) += bfin_gpio.o
13obj-$(CONFIG_BF561) += bfin_gpio.o
12obj-$(CONFIG_MODULES) += module.o 14obj-$(CONFIG_MODULES) += module.o
13obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o 15obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
14obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o 16obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
17obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index e455f4504509..b56b2741cdea 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -32,11 +32,10 @@
32#include <linux/kernel_stat.h> 32#include <linux/kernel_stat.h>
33#include <linux/ptrace.h> 33#include <linux/ptrace.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <asm/irq.h> 35#include <linux/irq.h>
36#include <asm/thread_info.h> 36#include <linux/thread_info.h>
37 37
38#define DEFINE(sym, val) \ 38#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
39 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
40 39
41int main(void) 40int main(void)
42{ 41{
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 069a896a8f26..7cf02f02a1db 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -34,6 +34,7 @@
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/param.h> 35#include <linux/param.h>
36 36
37#include <asm/blackfin.h>
37#include <asm/dma.h> 38#include <asm/dma.h>
38#include <asm/cacheflush.h> 39#include <asm/cacheflush.h>
39 40
@@ -45,67 +46,6 @@
45***************************************************************************/ 46***************************************************************************/
46 47
47static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL]; 48static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
48#if defined (CONFIG_BF561)
49static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
50 (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
51 (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
52 (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
53 (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
54 (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
55 (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
56 (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
57 (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
58 (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
59 (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
60 (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
61 (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
62 (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
63 (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
64 (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
65 (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
66 (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
67 (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
68 (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
69 (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
70 (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
71 (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
72 (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
73 (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
74 (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
75 (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
76 (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
77 (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
78 (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
79 (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
80 (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
81 (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
82 (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
83 (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
84 (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
85 (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
86};
87#else
88static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
89 (struct dma_register *) DMA0_NEXT_DESC_PTR,
90 (struct dma_register *) DMA1_NEXT_DESC_PTR,
91 (struct dma_register *) DMA2_NEXT_DESC_PTR,
92 (struct dma_register *) DMA3_NEXT_DESC_PTR,
93 (struct dma_register *) DMA4_NEXT_DESC_PTR,
94 (struct dma_register *) DMA5_NEXT_DESC_PTR,
95 (struct dma_register *) DMA6_NEXT_DESC_PTR,
96 (struct dma_register *) DMA7_NEXT_DESC_PTR,
97#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
98 (struct dma_register *) DMA8_NEXT_DESC_PTR,
99 (struct dma_register *) DMA9_NEXT_DESC_PTR,
100 (struct dma_register *) DMA10_NEXT_DESC_PTR,
101 (struct dma_register *) DMA11_NEXT_DESC_PTR,
102#endif
103 (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
104 (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
105 (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
106 (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
107};
108#endif
109 49
110/*------------------------------------------------------------------------------ 50/*------------------------------------------------------------------------------
111 * Set the Buffer Clear bit in the Configuration register of specific DMA 51 * Set the Buffer Clear bit in the Configuration register of specific DMA
@@ -138,149 +78,6 @@ static int __init blackfin_dma_init(void)
138 78
139arch_initcall(blackfin_dma_init); 79arch_initcall(blackfin_dma_init);
140 80
141/*
142 * Form the channel find the irq number for that channel.
143 */
144#if !defined(CONFIG_BF561)
145
146static int bf533_channel2irq(unsigned int channel)
147{
148 int ret_irq = -1;
149
150 switch (channel) {
151 case CH_PPI:
152 ret_irq = IRQ_PPI;
153 break;
154
155#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
156 case CH_EMAC_RX:
157 ret_irq = IRQ_MAC_RX;
158 break;
159
160 case CH_EMAC_TX:
161 ret_irq = IRQ_MAC_TX;
162 break;
163
164 case CH_UART1_RX:
165 ret_irq = IRQ_UART1_RX;
166 break;
167
168 case CH_UART1_TX:
169 ret_irq = IRQ_UART1_TX;
170 break;
171#endif
172
173 case CH_SPORT0_RX:
174 ret_irq = IRQ_SPORT0_RX;
175 break;
176
177 case CH_SPORT0_TX:
178 ret_irq = IRQ_SPORT0_TX;
179 break;
180
181 case CH_SPORT1_RX:
182 ret_irq = IRQ_SPORT1_RX;
183 break;
184
185 case CH_SPORT1_TX:
186 ret_irq = IRQ_SPORT1_TX;
187 break;
188
189 case CH_SPI:
190 ret_irq = IRQ_SPI;
191 break;
192
193 case CH_UART_RX:
194 ret_irq = IRQ_UART_RX;
195 break;
196
197 case CH_UART_TX:
198 ret_irq = IRQ_UART_TX;
199 break;
200
201 case CH_MEM_STREAM0_SRC:
202 case CH_MEM_STREAM0_DEST:
203 ret_irq = IRQ_MEM_DMA0;
204 break;
205
206 case CH_MEM_STREAM1_SRC:
207 case CH_MEM_STREAM1_DEST:
208 ret_irq = IRQ_MEM_DMA1;
209 break;
210 }
211 return ret_irq;
212}
213
214# define channel2irq(channel) bf533_channel2irq(channel)
215
216#else
217
218static int bf561_channel2irq(unsigned int channel)
219{
220 int ret_irq = -1;
221
222 switch (channel) {
223 case CH_PPI0:
224 ret_irq = IRQ_PPI0;
225 break;
226 case CH_PPI1:
227 ret_irq = IRQ_PPI1;
228 break;
229 case CH_SPORT0_RX:
230 ret_irq = IRQ_SPORT0_RX;
231 break;
232 case CH_SPORT0_TX:
233 ret_irq = IRQ_SPORT0_TX;
234 break;
235 case CH_SPORT1_RX:
236 ret_irq = IRQ_SPORT1_RX;
237 break;
238 case CH_SPORT1_TX:
239 ret_irq = IRQ_SPORT1_TX;
240 break;
241 case CH_SPI:
242 ret_irq = IRQ_SPI;
243 break;
244 case CH_UART_RX:
245 ret_irq = IRQ_UART_RX;
246 break;
247 case CH_UART_TX:
248 ret_irq = IRQ_UART_TX;
249 break;
250
251 case CH_MEM_STREAM0_SRC:
252 case CH_MEM_STREAM0_DEST:
253 ret_irq = IRQ_MEM_DMA0;
254 break;
255 case CH_MEM_STREAM1_SRC:
256 case CH_MEM_STREAM1_DEST:
257 ret_irq = IRQ_MEM_DMA1;
258 break;
259 case CH_MEM_STREAM2_SRC:
260 case CH_MEM_STREAM2_DEST:
261 ret_irq = IRQ_MEM_DMA2;
262 break;
263 case CH_MEM_STREAM3_SRC:
264 case CH_MEM_STREAM3_DEST:
265 ret_irq = IRQ_MEM_DMA3;
266 break;
267
268 case CH_IMEM_STREAM0_SRC:
269 case CH_IMEM_STREAM0_DEST:
270 ret_irq = IRQ_IMEM_DMA0;
271 break;
272 case CH_IMEM_STREAM1_SRC:
273 case CH_IMEM_STREAM1_DEST:
274 ret_irq = IRQ_IMEM_DMA1;
275 break;
276 }
277 return ret_irq;
278}
279
280# define channel2irq(channel) bf561_channel2irq(channel)
281
282#endif
283
284/*------------------------------------------------------------------------------ 81/*------------------------------------------------------------------------------
285 * Request the specific DMA channel from the system. 82 * Request the specific DMA channel from the system.
286 *-----------------------------------------------------------------------------*/ 83 *-----------------------------------------------------------------------------*/
@@ -535,7 +332,7 @@ set_bfin_dma_config(char direction, char flow_mode,
535} 332}
536EXPORT_SYMBOL(set_bfin_dma_config); 333EXPORT_SYMBOL(set_bfin_dma_config);
537 334
538void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg) 335void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
539{ 336{
540 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE 337 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
541 && channel < MAX_BLACKFIN_DMA_CHANNEL)); 338 && channel < MAX_BLACKFIN_DMA_CHANNEL));
@@ -604,7 +401,7 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
604 401
605 if (size <= 0) 402 if (size <= 0)
606 return NULL; 403 return NULL;
607 404
608 local_irq_save(flags); 405 local_irq_save(flags);
609 406
610 if ((unsigned long)src < memory_end) 407 if ((unsigned long)src < memory_end)
@@ -748,7 +545,6 @@ void *dma_memcpy(void *dest, const void *src, size_t size)
748 addr = __dma_memcpy(dest+bulk, src+bulk, rest); 545 addr = __dma_memcpy(dest+bulk, src+bulk, rest);
749 return addr; 546 return addr;
750} 547}
751
752EXPORT_SYMBOL(dma_memcpy); 548EXPORT_SYMBOL(dma_memcpy);
753 549
754void *safe_dma_memcpy(void *dest, const void *src, size_t size) 550void *safe_dma_memcpy(void *dest, const void *src, size_t size)
@@ -761,14 +557,13 @@ EXPORT_SYMBOL(safe_dma_memcpy);
761 557
762void dma_outsb(void __iomem *addr, const void *buf, unsigned short len) 558void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
763{ 559{
764
765 unsigned long flags; 560 unsigned long flags;
766 561
767 local_irq_save(flags); 562 local_irq_save(flags);
768
769 blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
770 563
771 bfin_write_MDMA_D0_START_ADDR(addr); 564 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
565
566 bfin_write_MDMA_D0_START_ADDR(addr);
772 bfin_write_MDMA_D0_X_COUNT(len); 567 bfin_write_MDMA_D0_X_COUNT(len);
773 bfin_write_MDMA_D0_X_MODIFY(0); 568 bfin_write_MDMA_D0_X_MODIFY(0);
774 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 569 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -796,9 +591,9 @@ EXPORT_SYMBOL(dma_outsb);
796void dma_insb(const void __iomem *addr, void *buf, unsigned short len) 591void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
797{ 592{
798 unsigned long flags; 593 unsigned long flags;
799 594
800 local_irq_save(flags); 595 local_irq_save(flags);
801 bfin_write_MDMA_D0_START_ADDR(buf); 596 bfin_write_MDMA_D0_START_ADDR(buf);
802 bfin_write_MDMA_D0_X_COUNT(len); 597 bfin_write_MDMA_D0_X_COUNT(len);
803 bfin_write_MDMA_D0_X_MODIFY(1); 598 bfin_write_MDMA_D0_X_MODIFY(1);
804 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 599 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -827,12 +622,12 @@ EXPORT_SYMBOL(dma_insb);
827void dma_outsw(void __iomem *addr, const void *buf, unsigned short len) 622void dma_outsw(void __iomem *addr, const void *buf, unsigned short len)
828{ 623{
829 unsigned long flags; 624 unsigned long flags;
830 625
831 local_irq_save(flags); 626 local_irq_save(flags);
832
833 blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
834 627
835 bfin_write_MDMA_D0_START_ADDR(addr); 628 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
629
630 bfin_write_MDMA_D0_START_ADDR(addr);
836 bfin_write_MDMA_D0_X_COUNT(len); 631 bfin_write_MDMA_D0_X_COUNT(len);
837 bfin_write_MDMA_D0_X_MODIFY(0); 632 bfin_write_MDMA_D0_X_MODIFY(0);
838 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 633 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -859,10 +654,10 @@ EXPORT_SYMBOL(dma_outsw);
859void dma_insw(const void __iomem *addr, void *buf, unsigned short len) 654void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
860{ 655{
861 unsigned long flags; 656 unsigned long flags;
862 657
863 local_irq_save(flags); 658 local_irq_save(flags);
864 659
865 bfin_write_MDMA_D0_START_ADDR(buf); 660 bfin_write_MDMA_D0_START_ADDR(buf);
866 bfin_write_MDMA_D0_X_COUNT(len); 661 bfin_write_MDMA_D0_X_COUNT(len);
867 bfin_write_MDMA_D0_X_MODIFY(2); 662 bfin_write_MDMA_D0_X_MODIFY(2);
868 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 663 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -891,12 +686,12 @@ EXPORT_SYMBOL(dma_insw);
891void dma_outsl(void __iomem *addr, const void *buf, unsigned short len) 686void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
892{ 687{
893 unsigned long flags; 688 unsigned long flags;
894 689
895 local_irq_save(flags); 690 local_irq_save(flags);
896
897 blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
898 691
899 bfin_write_MDMA_D0_START_ADDR(addr); 692 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
693
694 bfin_write_MDMA_D0_START_ADDR(addr);
900 bfin_write_MDMA_D0_X_COUNT(len); 695 bfin_write_MDMA_D0_X_COUNT(len);
901 bfin_write_MDMA_D0_X_MODIFY(0); 696 bfin_write_MDMA_D0_X_MODIFY(0);
902 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 697 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -923,10 +718,10 @@ EXPORT_SYMBOL(dma_outsl);
923void dma_insl(const void __iomem *addr, void *buf, unsigned short len) 718void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
924{ 719{
925 unsigned long flags; 720 unsigned long flags;
926 721
927 local_irq_save(flags); 722 local_irq_save(flags);
928 723
929 bfin_write_MDMA_D0_START_ADDR(buf); 724 bfin_write_MDMA_D0_START_ADDR(buf);
930 bfin_write_MDMA_D0_X_COUNT(len); 725 bfin_write_MDMA_D0_X_COUNT(len);
931 bfin_write_MDMA_D0_X_MODIFY(4); 726 bfin_write_MDMA_D0_X_MODIFY(4);
932 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 727 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index bb1f4fb2467c..bafcfa52142b 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -162,7 +162,7 @@ static void port_setup(unsigned short gpio, unsigned short usage)
162 162
163static void default_gpio(unsigned short gpio) 163static void default_gpio(unsigned short gpio)
164{ 164{
165 unsigned short bank,bitmask; 165 unsigned short bank, bitmask;
166 166
167 bank = gpio_bank(gpio); 167 bank = gpio_bank(gpio);
168 bitmask = gpio_bit(gpio); 168 bitmask = gpio_bit(gpio);
@@ -183,7 +183,7 @@ static int __init bfin_gpio_init(void)
183 183
184 printk(KERN_INFO "Blackfin GPIO Controller\n"); 184 printk(KERN_INFO "Blackfin GPIO Controller\n");
185 185
186 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) 186 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
187 reserved_map[gpio_bank(i)] = 0; 187 reserved_map[gpio_bank(i)] = 0;
188 188
189#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) 189#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
@@ -478,7 +478,7 @@ u32 gpio_pm_setup(void)
478 u32 sic_iwr = 0; 478 u32 sic_iwr = 0;
479 u16 bank, mask, i, gpio; 479 u16 bank, mask, i, gpio;
480 480
481 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { 481 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
482 mask = wakeup_map[gpio_bank(i)]; 482 mask = wakeup_map[gpio_bank(i)];
483 bank = gpio_bank(i); 483 bank = gpio_bank(i);
484 484
@@ -522,12 +522,11 @@ u32 gpio_pm_setup(void)
522 return IWR_ENABLE_ALL; 522 return IWR_ENABLE_ALL;
523} 523}
524 524
525
526void gpio_pm_restore(void) 525void gpio_pm_restore(void)
527{ 526{
528 u16 bank, mask, i; 527 u16 bank, mask, i;
529 528
530 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { 529 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
531 mask = wakeup_map[gpio_bank(i)]; 530 mask = wakeup_map[gpio_bank(i)];
532 bank = gpio_bank(i); 531 bank = gpio_bank(i);
533 532
@@ -591,7 +590,6 @@ int gpio_request(unsigned short gpio, const char *label)
591} 590}
592EXPORT_SYMBOL(gpio_request); 591EXPORT_SYMBOL(gpio_request);
593 592
594
595void gpio_free(unsigned short gpio) 593void gpio_free(unsigned short gpio)
596{ 594{
597 unsigned long flags; 595 unsigned long flags;
@@ -616,7 +614,6 @@ void gpio_free(unsigned short gpio)
616} 614}
617EXPORT_SYMBOL(gpio_free); 615EXPORT_SYMBOL(gpio_free);
618 616
619
620void gpio_direction_input(unsigned short gpio) 617void gpio_direction_input(unsigned short gpio)
621{ 618{
622 unsigned long flags; 619 unsigned long flags;
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
index f64ecb638fab..70455949cfd2 100644
--- a/arch/blackfin/kernel/bfin_ksyms.c
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -28,10 +28,11 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <asm/irq.h> 31#include <linux/irq.h>
32#include <linux/uaccess.h>
33
32#include <asm/checksum.h> 34#include <asm/checksum.h>
33#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
34#include <asm/uaccess.h>
35 36
36/* platform dependent support */ 37/* platform dependent support */
37 38
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cacheinit.c
new file mode 100644
index 000000000000..4d41a40e8133
--- /dev/null
+++ b/arch/blackfin/kernel/cacheinit.c
@@ -0,0 +1,66 @@
1/*
2 * Copyright 2004-2007 Analog Devices Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/cpu.h>
21
22#include <asm/cacheflush.h>
23#include <asm/blackfin.h>
24#include <asm/cplbinit.h>
25
26#if defined(CONFIG_BLKFIN_CACHE)
27void bfin_icache_init(void)
28{
29 unsigned long *table = icplb_table;
30 unsigned long ctrl;
31 int i;
32
33 for (i = 0; i < MAX_CPLBS; i++) {
34 unsigned long addr = *table++;
35 unsigned long data = *table++;
36 if (addr == (unsigned long)-1)
37 break;
38 bfin_write32(ICPLB_ADDR0 + i * 4, addr);
39 bfin_write32(ICPLB_DATA0 + i * 4, data);
40 }
41 ctrl = bfin_read_IMEM_CONTROL();
42 ctrl |= IMC | ENICPLB;
43 bfin_write_IMEM_CONTROL(ctrl);
44}
45#endif
46
47#if defined(CONFIG_BLKFIN_DCACHE)
48void bfin_dcache_init(void)
49{
50 unsigned long *table = dcplb_table;
51 unsigned long ctrl;
52 int i;
53
54 for (i = 0; i < MAX_CPLBS; i++) {
55 unsigned long addr = *table++;
56 unsigned long data = *table++;
57 if (addr == (unsigned long)-1)
58 break;
59 bfin_write32(DCPLB_ADDR0 + i * 4, addr);
60 bfin_write32(DCPLB_DATA0 + i * 4, data);
61 }
62 ctrl = bfin_read_DMEM_CONTROL();
63 ctrl |= DMEM_CNTR;
64 bfin_write_DMEM_CONTROL(ctrl);
65}
66#endif
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c
new file mode 100644
index 000000000000..bbdb403fcb55
--- /dev/null
+++ b/arch/blackfin/kernel/cplbinit.c
@@ -0,0 +1,433 @@
1/*
2 * Blackfin CPLB initialization
3 *
4 * Copyright 2004-2007 Analog Devices Inc.
5 *
6 * Bugs: Enter bugs at http://blackfin.uclinux.org/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23#include <linux/module.h>
24
25#include <asm/blackfin.h>
26#include <asm/cplbinit.h>
27
28u_long icplb_table[MAX_CPLBS+1];
29u_long dcplb_table[MAX_CPLBS+1];
30
31#ifdef CONFIG_CPLB_SWITCH_TAB_L1
32u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
33u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
34
35#ifdef CONFIG_CPLB_INFO
36u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
37u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
38#endif /* CONFIG_CPLB_INFO */
39
40#else
41
42u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
43u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
44
45#ifdef CONFIG_CPLB_INFO
46u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
47u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
48#endif /* CONFIG_CPLB_INFO */
49
50#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
51
52struct s_cplb {
53 struct cplb_tab init_i;
54 struct cplb_tab init_d;
55 struct cplb_tab switch_i;
56 struct cplb_tab switch_d;
57};
58
59#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
60static struct cplb_desc cplb_data[] = {
61 {
62 .start = 0,
63 .end = SIZE_1K,
64 .psize = SIZE_1K,
65 .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
66 .i_conf = SDRAM_OOPS,
67 .d_conf = SDRAM_OOPS,
68#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
69 .valid = 1,
70#else
71 .valid = 0,
72#endif
73 .name = "ZERO Pointer Saveguard",
74 },
75 {
76 .start = L1_CODE_START,
77 .end = L1_CODE_START + L1_CODE_LENGTH,
78 .psize = SIZE_4M,
79 .attr = INITIAL_T | SWITCH_T | I_CPLB,
80 .i_conf = L1_IMEMORY,
81 .d_conf = 0,
82 .valid = 1,
83 .name = "L1 I-Memory",
84 },
85 {
86 .start = L1_DATA_A_START,
87 .end = L1_DATA_B_START + L1_DATA_B_LENGTH,
88 .psize = SIZE_4M,
89 .attr = INITIAL_T | SWITCH_T | D_CPLB,
90 .i_conf = 0,
91 .d_conf = L1_DMEMORY,
92#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
93 .valid = 1,
94#else
95 .valid = 0,
96#endif
97 .name = "L1 D-Memory",
98 },
99 {
100 .start = 0,
101 .end = 0, /* dynamic */
102 .psize = 0,
103 .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
104 .i_conf = SDRAM_IGENERIC,
105 .d_conf = SDRAM_DGENERIC,
106 .valid = 1,
107 .name = "SDRAM Kernel",
108 },
109 {
110 .start = 0, /* dynamic */
111 .end = 0, /* dynamic */
112 .psize = 0,
113 .attr = INITIAL_T | SWITCH_T | D_CPLB,
114 .i_conf = SDRAM_IGENERIC,
115 .d_conf = SDRAM_DNON_CHBL,
116 .valid = 1,
117 .name = "SDRAM RAM MTD",
118 },
119 {
120 .start = 0, /* dynamic */
121 .end = 0, /* dynamic */
122 .psize = SIZE_1M,
123 .attr = INITIAL_T | SWITCH_T | D_CPLB,
124 .d_conf = SDRAM_DNON_CHBL,
125 .valid = 1,
126 .name = "SDRAM Uncached DMA ZONE",
127 },
128 {
129 .start = 0, /* dynamic */
130 .end = 0, /* dynamic */
131 .psize = 0,
132 .attr = SWITCH_T | D_CPLB,
133 .i_conf = 0, /* dynamic */
134 .d_conf = 0, /* dynamic */
135 .valid = 1,
136 .name = "SDRAM Reserved Memory",
137 },
138 {
139 .start = ASYNC_BANK0_BASE,
140 .end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
141 .psize = 0,
142 .attr = SWITCH_T | D_CPLB,
143 .d_conf = SDRAM_EBIU,
144 .valid = 1,
145 .name = "ASYNC Memory",
146 },
147 {
148#if defined(CONFIG_BF561)
149 .start = L2_SRAM,
150 .end = L2_SRAM_END,
151 .psize = SIZE_1M,
152 .attr = SWITCH_T | D_CPLB,
153 .i_conf = L2_MEMORY,
154 .d_conf = L2_MEMORY,
155 .valid = 1,
156#else
157 .valid = 0,
158#endif
159 .name = "L2 Memory",
160 }
161};
162
163static u16 __init lock_kernel_check(u32 start, u32 end)
164{
165 if ((start <= (u32) _stext && end >= (u32) _end)
166 || (start >= (u32) _stext && end <= (u32) _end))
167 return IN_KERNEL;
168 return 0;
169}
170
171static unsigned short __init
172fill_cplbtab(struct cplb_tab *table,
173 unsigned long start, unsigned long end,
174 unsigned long block_size, unsigned long cplb_data)
175{
176 int i;
177
178 switch (block_size) {
179 case SIZE_4M:
180 i = 3;
181 break;
182 case SIZE_1M:
183 i = 2;
184 break;
185 case SIZE_4K:
186 i = 1;
187 break;
188 case SIZE_1K:
189 default:
190 i = 0;
191 break;
192 }
193
194 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
195
196 while ((start < end) && (table->pos < table->size)) {
197
198 table->tab[table->pos++] = start;
199
200 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
201 table->tab[table->pos++] =
202 cplb_data | CPLB_LOCK | CPLB_DIRTY;
203 else
204 table->tab[table->pos++] = cplb_data;
205
206 start += block_size;
207 }
208 return 0;
209}
210
211static unsigned short __init
212close_cplbtab(struct cplb_tab *table)
213{
214
215 while (table->pos < table->size) {
216
217 table->tab[table->pos++] = 0;
218 table->tab[table->pos++] = 0; /* !CPLB_VALID */
219 }
220 return 0;
221}
222
223/* helper function */
224static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
225{
226 if (cplb_data[i].psize) {
227 fill_cplbtab(t,
228 cplb_data[i].start,
229 cplb_data[i].end,
230 cplb_data[i].psize,
231 cplb_data[i].i_conf);
232 } else {
233#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
234 if (i == SDRAM_KERN) {
235 fill_cplbtab(t,
236 cplb_data[i].start,
237 cplb_data[i].end,
238 SIZE_4M,
239 cplb_data[i].i_conf);
240 } else
241#endif
242 {
243 fill_cplbtab(t,
244 cplb_data[i].start,
245 a_start,
246 SIZE_1M,
247 cplb_data[i].i_conf);
248 fill_cplbtab(t,
249 a_start,
250 a_end,
251 SIZE_4M,
252 cplb_data[i].i_conf);
253 fill_cplbtab(t, a_end,
254 cplb_data[i].end,
255 SIZE_1M,
256 cplb_data[i].i_conf);
257 }
258 }
259}
260
261static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
262{
263 if (cplb_data[i].psize) {
264 fill_cplbtab(t,
265 cplb_data[i].start,
266 cplb_data[i].end,
267 cplb_data[i].psize,
268 cplb_data[i].d_conf);
269 } else {
270 fill_cplbtab(t,
271 cplb_data[i].start,
272 a_start, SIZE_1M,
273 cplb_data[i].d_conf);
274 fill_cplbtab(t, a_start,
275 a_end, SIZE_4M,
276 cplb_data[i].d_conf);
277 fill_cplbtab(t, a_end,
278 cplb_data[i].end,
279 SIZE_1M,
280 cplb_data[i].d_conf);
281 }
282}
283
284void __init generate_cpl_tables(void)
285{
286
287 u16 i, j, process;
288 u32 a_start, a_end, as, ae, as_1m;
289
290 struct cplb_tab *t_i = NULL;
291 struct cplb_tab *t_d = NULL;
292 struct s_cplb cplb;
293
294 cplb.init_i.size = MAX_CPLBS;
295 cplb.init_d.size = MAX_CPLBS;
296 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
297 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
298
299 cplb.init_i.pos = 0;
300 cplb.init_d.pos = 0;
301 cplb.switch_i.pos = 0;
302 cplb.switch_d.pos = 0;
303
304 cplb.init_i.tab = icplb_table;
305 cplb.init_d.tab = dcplb_table;
306 cplb.switch_i.tab = ipdt_table;
307 cplb.switch_d.tab = dpdt_table;
308
309 cplb_data[SDRAM_KERN].end = memory_end;
310
311#ifdef CONFIG_MTD_UCLINUX
312 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
313 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
314 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
315# if defined(CONFIG_ROMFS_FS)
316 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
317
318 /*
319 * The ROMFS_FS size is often not multiple of 1MB.
320 * This can cause multiple CPLB sets covering the same memory area.
321 * This will then cause multiple CPLB hit exceptions.
322 * Workaround: We ensure a contiguous memory area by extending the kernel
323 * memory section over the mtd section.
324 * For ROMFS_FS memory must be covered with ICPLBs anyways.
325 * So there is no difference between kernel and mtd memory setup.
326 */
327
328 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
329 cplb_data[SDRAM_RAM_MTD].valid = 0;
330
331# endif
332#else
333 cplb_data[SDRAM_RAM_MTD].valid = 0;
334#endif
335
336 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
337 cplb_data[SDRAM_DMAZ].end = _ramend;
338
339 cplb_data[RES_MEM].start = _ramend;
340 cplb_data[RES_MEM].end = physical_mem_end;
341
342 if (reserved_mem_dcache_on)
343 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
344 else
345 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
346
347 if (reserved_mem_icache_on)
348 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
349 else
350 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
351
352 for (i = ZERO_P; i <= L2_MEM; i++) {
353 if (!cplb_data[i].valid)
354 continue;
355
356 as_1m = cplb_data[i].start % SIZE_1M;
357
358 /* We need to make sure all sections are properly 1M aligned
359 * However between Kernel Memory and the Kernel mtd section, depending on the
360 * rootfs size, there can be overlapping memory areas.
361 */
362
363 if (as_1m && i != L1I_MEM && i != L1D_MEM) {
364#ifdef CONFIG_MTD_UCLINUX
365 if (i == SDRAM_RAM_MTD) {
366 if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
367 cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
368 else
369 cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
370 } else
371#endif
372 printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
373 cplb_data[i].name, cplb_data[i].start);
374 }
375
376 as = cplb_data[i].start % SIZE_4M;
377 ae = cplb_data[i].end % SIZE_4M;
378
379 if (as)
380 a_start = cplb_data[i].start + (SIZE_4M - (as));
381 else
382 a_start = cplb_data[i].start;
383
384 a_end = cplb_data[i].end - ae;
385
386 for (j = INITIAL_T; j <= SWITCH_T; j++) {
387
388 switch (j) {
389 case INITIAL_T:
390 if (cplb_data[i].attr & INITIAL_T) {
391 t_i = &cplb.init_i;
392 t_d = &cplb.init_d;
393 process = 1;
394 } else
395 process = 0;
396 break;
397 case SWITCH_T:
398 if (cplb_data[i].attr & SWITCH_T) {
399 t_i = &cplb.switch_i;
400 t_d = &cplb.switch_d;
401 process = 1;
402 } else
403 process = 0;
404 break;
405 default:
406 process = 0;
407 break;
408 }
409
410 if (!process)
411 continue;
412 if (cplb_data[i].attr & I_CPLB)
413 __fill_code_cplbtab(t_i, i, a_start, a_end);
414
415 if (cplb_data[i].attr & D_CPLB)
416 __fill_data_cplbtab(t_d, i, a_start, a_end);
417 }
418 }
419
420/* close tables */
421
422 close_cplbtab(&cplb.init_i);
423 close_cplbtab(&cplb.init_d);
424
425 cplb.init_i.tab[cplb.init_i.pos] = -1;
426 cplb.init_d.tab[cplb.init_d.pos] = -1;
427 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
428 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
429
430}
431
432#endif
433
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 539eb24e062f..ea48d5b13f11 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -34,8 +34,8 @@
34#include <linux/spinlock.h> 34#include <linux/spinlock.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/io.h>
37#include <asm/cacheflush.h> 38#include <asm/cacheflush.h>
38#include <asm/io.h>
39#include <asm/bfin-global.h> 39#include <asm/bfin-global.h>
40 40
41static spinlock_t dma_page_lock; 41static spinlock_t dma_page_lock;
@@ -159,10 +159,13 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
159 159
160 BUG_ON(direction == DMA_NONE); 160 BUG_ON(direction == DMA_NONE);
161 161
162 for (i = 0; i < nents; i++) 162 for (i = 0; i < nents; i++, sg++) {
163 invalidate_dcache_range(sg_dma_address(&sg[i]), 163 sg->dma_address = page_address(sg->page) + sg->offset;
164 sg_dma_address(&sg[i]) + 164
165 sg_dma_len(&sg[i])); 165 invalidate_dcache_range(sg_dma_address(sg),
166 sg_dma_address(sg) +
167 sg_dma_len(sg));
168 }
166 169
167 return nents; 170 return nents;
168} 171}
diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c
index 8b89c99f9dfa..0fcba74840b7 100644
--- a/arch/blackfin/kernel/dualcore_test.c
+++ b/arch/blackfin/kernel/dualcore_test.c
@@ -30,19 +30,19 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/module.h> 31#include <linux/module.h>
32 32
33static int *testarg = (int*)0xfeb00000; 33static int *testarg = (int *)0xfeb00000;
34 34
35static int test_init(void) 35static int test_init(void)
36{ 36{
37 *testarg = 1; 37 *testarg = 1;
38 printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", 38 printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
39 *testarg, testarg); 39 *testarg, testarg);
40 return 0; 40 return 0;
41} 41}
42 42
43static void test_exit(void) 43static void test_exit(void)
44{ 44{
45 printk("Dual core test module removed: testarg = [%d]\n", *testarg); 45 printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg);
46} 46}
47 47
48module_init(test_init); 48module_init(test_init);
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
new file mode 100644
index 000000000000..d8b1ebc70996
--- /dev/null
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -0,0 +1,132 @@
1/*
2 * This file contains sequences of code that will be copied to a
3 * fixed location, defined in <asm/atomic_seq.h>. The interrupt
4 * handlers ensure that these sequences appear to be atomic when
5 * executed from userspace.
6 * These are aligned to 16 bytes, so that we have some space to replace
7 * these sequences with something else (e.g. kernel traps if we ever do
8 * BF561 SMP).
9 */
10#include <linux/linkage.h>
11#include <linux/unistd.h>
12#include <asm/entry.h>
13
14.text
15ENTRY(_fixed_code_start)
16
17.align 16
18ENTRY(_sigreturn_stub)
19 P0 = __NR_rt_sigreturn;
20 EXCPT 0;
21 /* Speculative execution paranoia. */
220: JUMP.S 0b;
23ENDPROC (_sigreturn_stub)
24
25.align 16
26 /*
27 * Atomic swap, 8 bit.
28 * Inputs: P0: memory address to use
29 * R1: value to store
30 * Output: R0: old contents of the memory address, zero extended.
31 */
32ENTRY(_atomic_xchg32)
33 R0 = [P0];
34 [P0] = R1;
35 rts;
36ENDPROC (_atomic_xchg32)
37
38.align 16
39 /*
40 * Compare and swap, 32 bit.
41 * Inputs: P0: memory address to use
42 * R1: compare value
43 * R2: new value to store
44 * The new value is stored if the contents of the memory
45 * address is equal to the compare value.
46 * Output: R0: old contents of the memory address.
47 */
48ENTRY(_atomic_cas32)
49 R0 = [P0];
50 CC = R0 == R1;
51 IF !CC JUMP 1f;
52 [P0] = R2;
531:
54 rts;
55ENDPROC (_atomic_cas32)
56
57.align 16
58 /*
59 * Atomic add, 32 bit.
60 * Inputs: P0: memory address to use
61 * R0: value to add
62 * Outputs: R0: new contents of the memory address.
63 * R1: previous contents of the memory address.
64 */
65ENTRY(_atomic_add32)
66 R1 = [P0];
67 R0 = R1 + R0;
68 [P0] = R0;
69 rts;
70ENDPROC (_atomic_add32)
71
72.align 16
73 /*
74 * Atomic sub, 32 bit.
75 * Inputs: P0: memory address to use
76 * R0: value to subtract
77 * Outputs: R0: new contents of the memory address.
78 * R1: previous contents of the memory address.
79 */
80ENTRY(_atomic_sub32)
81 R1 = [P0];
82 R0 = R1 - R0;
83 [P0] = R0;
84 rts;
85ENDPROC (_atomic_sub32)
86
87.align 16
88 /*
89 * Atomic ior, 32 bit.
90 * Inputs: P0: memory address to use
91 * R0: value to ior
92 * Outputs: R0: new contents of the memory address.
93 * R1: previous contents of the memory address.
94 */
95ENTRY(_atomic_ior32)
96 R1 = [P0];
97 R0 = R1 | R0;
98 [P0] = R0;
99 rts;
100ENDPROC (_atomic_ior32)
101
102.align 16
103 /*
104 * Atomic ior, 32 bit.
105 * Inputs: P0: memory address to use
106 * R0: value to ior
107 * Outputs: R0: new contents of the memory address.
108 * R1: previous contents of the memory address.
109 */
110ENTRY(_atomic_and32)
111 R1 = [P0];
112 R0 = R1 & R0;
113 [P0] = R0;
114 rts;
115ENDPROC (_atomic_ior32)
116
117.align 16
118 /*
119 * Atomic ior, 32 bit.
120 * Inputs: P0: memory address to use
121 * R0: value to ior
122 * Outputs: R0: new contents of the memory address.
123 * R1: previous contents of the memory address.
124 */
125ENTRY(_atomic_xor32)
126 R1 = [P0];
127 R0 = R1 ^ R0;
128 [P0] = R0;
129 rts;
130ENDPROC (_atomic_ior32)
131
132ENTRY(_fixed_code_end)
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
index a92587b628b5..d188b2430536 100644
--- a/arch/blackfin/kernel/flat.c
+++ b/arch/blackfin/kernel/flat.c
@@ -36,24 +36,22 @@ unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
36 unsigned long val; 36 unsigned long val;
37 37
38 switch (type) { 38 switch (type) {
39 case FLAT_BFIN_RELOC_TYPE_16_BIT: 39 case FLAT_BFIN_RELOC_TYPE_16_BIT:
40 case FLAT_BFIN_RELOC_TYPE_16H_BIT: 40 case FLAT_BFIN_RELOC_TYPE_16H_BIT:
41 usptr = (unsigned short *)ptr; 41 usptr = (unsigned short *)ptr;
42 pr_debug("*usptr = %x", get_unaligned(usptr)); 42 pr_debug("*usptr = %x", get_unaligned(usptr));
43 val = get_unaligned(usptr); 43 val = get_unaligned(usptr);
44 val += *persistent; 44 val += *persistent;
45 break; 45 break;
46 46
47 case FLAT_BFIN_RELOC_TYPE_32_BIT: 47 case FLAT_BFIN_RELOC_TYPE_32_BIT:
48 pr_debug("*ptr = %lx", get_unaligned(ptr)); 48 pr_debug("*ptr = %lx", get_unaligned(ptr));
49 val = get_unaligned(ptr); 49 val = get_unaligned(ptr);
50 break; 50 break;
51 51
52 default: 52 default:
53 pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", 53 pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", type);
54 type); 54 return 0;
55
56 return 0;
57 } 55 }
58 56
59 /* 57 /*
@@ -81,21 +79,20 @@ void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
81 int type = (relval >> 26) & 7; 79 int type = (relval >> 26) & 7;
82 80
83 switch (type) { 81 switch (type) {
84 case FLAT_BFIN_RELOC_TYPE_16_BIT: 82 case FLAT_BFIN_RELOC_TYPE_16_BIT:
85 put_unaligned(addr, usptr); 83 put_unaligned(addr, usptr);
86 pr_debug("new value %x at %p", get_unaligned(usptr), 84 pr_debug("new value %x at %p", get_unaligned(usptr), usptr);
87 usptr); 85 break;
88 break;
89 86
90 case FLAT_BFIN_RELOC_TYPE_16H_BIT: 87 case FLAT_BFIN_RELOC_TYPE_16H_BIT:
91 put_unaligned(addr >> 16, usptr); 88 put_unaligned(addr >> 16, usptr);
92 pr_debug("new value %x", get_unaligned(usptr)); 89 pr_debug("new value %x", get_unaligned(usptr));
93 break; 90 break;
94 91
95 case FLAT_BFIN_RELOC_TYPE_32_BIT: 92 case FLAT_BFIN_RELOC_TYPE_32_BIT:
96 put_unaligned(addr, ptr); 93 put_unaligned(addr, ptr);
97 pr_debug("new ptr =%lx", get_unaligned(ptr)); 94 pr_debug("new ptr =%lx", get_unaligned(ptr));
98 break; 95 break;
99 } 96 }
100} 97}
101EXPORT_SYMBOL(bfin_put_addr_at_rp); 98EXPORT_SYMBOL(bfin_put_addr_at_rp);
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 80996a1a94ca..1fc001c7abda 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -82,7 +82,7 @@ int show_interrupts(struct seq_file *p, void *v)
82 seq_printf(p, ", %s", action->name); 82 seq_printf(p, ", %s", action->name);
83 83
84 seq_putc(p, '\n'); 84 seq_putc(p, '\n');
85 unlock: 85 unlock:
86 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 86 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
87 } else if (i == NR_IRQS) { 87 } else if (i == NR_IRQS) {
88 seq_printf(p, "Err: %10lu\n", irq_err_count); 88 seq_printf(p, "Err: %10lu\n", irq_err_count);
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
new file mode 100644
index 000000000000..a9c15515bfd7
--- /dev/null
+++ b/arch/blackfin/kernel/kgdb.c
@@ -0,0 +1,421 @@
1/*
2 * File: arch/blackfin/kernel/kgdb.c
3 * Based on:
4 * Author: Sonic Zhang
5 *
6 * Created:
7 * Description:
8 *
9 * Rev: $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
10 *
11 * Modified:
12 * Copyright 2005-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32#include <linux/string.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/smp.h>
36#include <linux/spinlock.h>
37#include <linux/delay.h>
38#include <linux/ptrace.h> /* for linux pt_regs struct */
39#include <linux/kgdb.h>
40#include <linux/console.h>
41#include <linux/init.h>
42#include <linux/debugger.h>
43#include <linux/errno.h>
44#include <linux/irq.h>
45#include <asm/system.h>
46#include <asm/traps.h>
47#include <asm/blackfin.h>
48
49/* Put the error code here just in case the user cares. */
50int gdb_bf533errcode;
51/* Likewise, the vector number here (since GDB only gets the signal
52 number through the usual means, and that's not very specific). */
53int gdb_bf533vector = -1;
54
55#if KGDB_MAX_NO_CPUS != 8
56#error change the definition of slavecpulocks
57#endif
58
59void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
60{
61 gdb_regs[BFIN_R0] = regs->r0;
62 gdb_regs[BFIN_R1] = regs->r1;
63 gdb_regs[BFIN_R2] = regs->r2;
64 gdb_regs[BFIN_R3] = regs->r3;
65 gdb_regs[BFIN_R4] = regs->r4;
66 gdb_regs[BFIN_R5] = regs->r5;
67 gdb_regs[BFIN_R6] = regs->r6;
68 gdb_regs[BFIN_R7] = regs->r7;
69 gdb_regs[BFIN_P0] = regs->p0;
70 gdb_regs[BFIN_P1] = regs->p1;
71 gdb_regs[BFIN_P2] = regs->p2;
72 gdb_regs[BFIN_P3] = regs->p3;
73 gdb_regs[BFIN_P4] = regs->p4;
74 gdb_regs[BFIN_P5] = regs->p5;
75 gdb_regs[BFIN_SP] = regs->reserved;
76 gdb_regs[BFIN_FP] = regs->fp;
77 gdb_regs[BFIN_I0] = regs->i0;
78 gdb_regs[BFIN_I1] = regs->i1;
79 gdb_regs[BFIN_I2] = regs->i2;
80 gdb_regs[BFIN_I3] = regs->i3;
81 gdb_regs[BFIN_M0] = regs->m0;
82 gdb_regs[BFIN_M1] = regs->m1;
83 gdb_regs[BFIN_M2] = regs->m2;
84 gdb_regs[BFIN_M3] = regs->m3;
85 gdb_regs[BFIN_B0] = regs->b0;
86 gdb_regs[BFIN_B1] = regs->b1;
87 gdb_regs[BFIN_B2] = regs->b2;
88 gdb_regs[BFIN_B3] = regs->b3;
89 gdb_regs[BFIN_L0] = regs->l0;
90 gdb_regs[BFIN_L1] = regs->l1;
91 gdb_regs[BFIN_L2] = regs->l2;
92 gdb_regs[BFIN_L3] = regs->l3;
93 gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
94 gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
95 gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
96 gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
97 gdb_regs[BFIN_ASTAT] = regs->astat;
98 gdb_regs[BFIN_RETS] = regs->rets;
99 gdb_regs[BFIN_LC0] = regs->lc0;
100 gdb_regs[BFIN_LT0] = regs->lt0;
101 gdb_regs[BFIN_LB0] = regs->lb0;
102 gdb_regs[BFIN_LC1] = regs->lc1;
103 gdb_regs[BFIN_LT1] = regs->lt1;
104 gdb_regs[BFIN_LB1] = regs->lb1;
105 gdb_regs[BFIN_CYCLES] = 0;
106 gdb_regs[BFIN_CYCLES2] = 0;
107 gdb_regs[BFIN_USP] = regs->usp;
108 gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
109 gdb_regs[BFIN_SYSCFG] = regs->syscfg;
110 gdb_regs[BFIN_RETI] = regs->pc;
111 gdb_regs[BFIN_RETX] = regs->retx;
112 gdb_regs[BFIN_RETN] = regs->retn;
113 gdb_regs[BFIN_RETE] = regs->rete;
114 gdb_regs[BFIN_PC] = regs->pc;
115 gdb_regs[BFIN_CC] = 0;
116 gdb_regs[BFIN_EXTRA1] = 0;
117 gdb_regs[BFIN_EXTRA2] = 0;
118 gdb_regs[BFIN_EXTRA3] = 0;
119 gdb_regs[BFIN_IPEND] = regs->ipend;
120}
121
122/*
123 * Extracts ebp, esp and eip values understandable by gdb from the values
124 * saved by switch_to.
125 * thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
126 * prior to entering switch_to is 8 greater then the value that is saved.
127 * If switch_to changes, change following code appropriately.
128 */
129void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
130{
131 gdb_regs[BFIN_SP] = p->thread.ksp;
132 gdb_regs[BFIN_PC] = p->thread.pc;
133 gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
134}
135
136void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
137{
138 regs->r0 = gdb_regs[BFIN_R0];
139 regs->r1 = gdb_regs[BFIN_R1];
140 regs->r2 = gdb_regs[BFIN_R2];
141 regs->r3 = gdb_regs[BFIN_R3];
142 regs->r4 = gdb_regs[BFIN_R4];
143 regs->r5 = gdb_regs[BFIN_R5];
144 regs->r6 = gdb_regs[BFIN_R6];
145 regs->r7 = gdb_regs[BFIN_R7];
146 regs->p0 = gdb_regs[BFIN_P0];
147 regs->p1 = gdb_regs[BFIN_P1];
148 regs->p2 = gdb_regs[BFIN_P2];
149 regs->p3 = gdb_regs[BFIN_P3];
150 regs->p4 = gdb_regs[BFIN_P4];
151 regs->p5 = gdb_regs[BFIN_P5];
152 regs->fp = gdb_regs[BFIN_FP];
153 regs->i0 = gdb_regs[BFIN_I0];
154 regs->i1 = gdb_regs[BFIN_I1];
155 regs->i2 = gdb_regs[BFIN_I2];
156 regs->i3 = gdb_regs[BFIN_I3];
157 regs->m0 = gdb_regs[BFIN_M0];
158 regs->m1 = gdb_regs[BFIN_M1];
159 regs->m2 = gdb_regs[BFIN_M2];
160 regs->m3 = gdb_regs[BFIN_M3];
161 regs->b0 = gdb_regs[BFIN_B0];
162 regs->b1 = gdb_regs[BFIN_B1];
163 regs->b2 = gdb_regs[BFIN_B2];
164 regs->b3 = gdb_regs[BFIN_B3];
165 regs->l0 = gdb_regs[BFIN_L0];
166 regs->l1 = gdb_regs[BFIN_L1];
167 regs->l2 = gdb_regs[BFIN_L2];
168 regs->l3 = gdb_regs[BFIN_L3];
169 regs->a0x = gdb_regs[BFIN_A0_DOT_X];
170 regs->a0w = gdb_regs[BFIN_A0_DOT_W];
171 regs->a1x = gdb_regs[BFIN_A1_DOT_X];
172 regs->a1w = gdb_regs[BFIN_A1_DOT_W];
173 regs->rets = gdb_regs[BFIN_RETS];
174 regs->lc0 = gdb_regs[BFIN_LC0];
175 regs->lt0 = gdb_regs[BFIN_LT0];
176 regs->lb0 = gdb_regs[BFIN_LB0];
177 regs->lc1 = gdb_regs[BFIN_LC1];
178 regs->lt1 = gdb_regs[BFIN_LT1];
179 regs->lb1 = gdb_regs[BFIN_LB1];
180 regs->usp = gdb_regs[BFIN_USP];
181 regs->syscfg = gdb_regs[BFIN_SYSCFG];
182 regs->retx = gdb_regs[BFIN_PC];
183 regs->retn = gdb_regs[BFIN_RETN];
184 regs->rete = gdb_regs[BFIN_RETE];
185 regs->pc = gdb_regs[BFIN_PC];
186
187#if 0 /* can't change these */
188 regs->astat = gdb_regs[BFIN_ASTAT];
189 regs->seqstat = gdb_regs[BFIN_SEQSTAT];
190 regs->ipend = gdb_regs[BFIN_IPEND];
191#endif
192}
193
194struct hw_breakpoint {
195 unsigned int occupied:1;
196 unsigned int skip:1;
197 unsigned int enabled:1;
198 unsigned int type:1;
199 unsigned int dataacc:2;
200 unsigned short count;
201 unsigned int addr;
202} breakinfo[HW_BREAKPOINT_NUM];
203
204int kgdb_arch_init(void)
205{
206 kgdb_remove_all_hw_break();
207 return 0;
208}
209
210int kgdb_set_hw_break(unsigned long addr)
211{
212 int breakno;
213 for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
214 if (!breakinfo[breakno].occupied) {
215 breakinfo[breakno].occupied = 1;
216 breakinfo[breakno].enabled = 1;
217 breakinfo[breakno].type = 1;
218 breakinfo[breakno].addr = addr;
219 return 0;
220 }
221
222 return -ENOSPC;
223}
224
225int kgdb_remove_hw_break(unsigned long addr)
226{
227 int breakno;
228 for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
229 if (breakinfo[breakno].addr == addr)
230 memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint));
231
232 return 0;
233}
234
235void kgdb_remove_all_hw_break(void)
236{
237 memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8);
238}
239
240/*
241void kgdb_show_info(void)
242{
243 printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
244 bfin_read_WPIA0(), bfin_read_WPIACNT0(),
245 bfin_read_WPIACTL(), bfin_read_WPSTAT());
246}
247*/
248
249void kgdb_correct_hw_break(void)
250{
251 int breakno;
252 int correctit;
253 uint32_t wpdactl = bfin_read_WPDACTL();
254
255 correctit = 0;
256 for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) {
257 if (breakinfo[breakno].type == 1) {
258 switch (breakno) {
259 case 0:
260 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) {
261 correctit = 1;
262 wpdactl &= ~(WPIREN01|EMUSW0);
263 wpdactl |= WPIAEN0|WPICNTEN0;
264 bfin_write_WPIA0(breakinfo[breakno].addr);
265 bfin_write_WPIACNT0(breakinfo[breakno].skip);
266 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) {
267 correctit = 1;
268 wpdactl &= ~WPIAEN0;
269 }
270 break;
271
272 case 1:
273 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) {
274 correctit = 1;
275 wpdactl &= ~(WPIREN01|EMUSW1);
276 wpdactl |= WPIAEN1|WPICNTEN1;
277 bfin_write_WPIA1(breakinfo[breakno].addr);
278 bfin_write_WPIACNT1(breakinfo[breakno].skip);
279 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) {
280 correctit = 1;
281 wpdactl &= ~WPIAEN1;
282 }
283 break;
284
285 case 2:
286 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) {
287 correctit = 1;
288 wpdactl &= ~(WPIREN23|EMUSW2);
289 wpdactl |= WPIAEN2|WPICNTEN2;
290 bfin_write_WPIA2(breakinfo[breakno].addr);
291 bfin_write_WPIACNT2(breakinfo[breakno].skip);
292 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) {
293 correctit = 1;
294 wpdactl &= ~WPIAEN2;
295 }
296 break;
297
298 case 3:
299 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) {
300 correctit = 1;
301 wpdactl &= ~(WPIREN23|EMUSW3);
302 wpdactl |= WPIAEN3|WPICNTEN3;
303 bfin_write_WPIA3(breakinfo[breakno].addr);
304 bfin_write_WPIACNT3(breakinfo[breakno].skip);
305 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) {
306 correctit = 1;
307 wpdactl &= ~WPIAEN3;
308 }
309 break;
310 case 4:
311 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) {
312 correctit = 1;
313 wpdactl &= ~(WPIREN45|EMUSW4);
314 wpdactl |= WPIAEN4|WPICNTEN4;
315 bfin_write_WPIA4(breakinfo[breakno].addr);
316 bfin_write_WPIACNT4(breakinfo[breakno].skip);
317 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) {
318 correctit = 1;
319 wpdactl &= ~WPIAEN4;
320 }
321 break;
322 case 5:
323 if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) {
324 correctit = 1;
325 wpdactl &= ~(WPIREN45|EMUSW5);
326 wpdactl |= WPIAEN5|WPICNTEN5;
327 bfin_write_WPIA5(breakinfo[breakno].addr);
328 bfin_write_WPIACNT5(breakinfo[breakno].skip);
329 } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) {
330 correctit = 1;
331 wpdactl &= ~WPIAEN5;
332 }
333 break;
334 }
335 }
336 }
337 if (correctit) {
338 wpdactl &= ~WPAND;
339 wpdactl |= WPPWR;
340 /*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
341 bfin_write_WPDACTL(wpdactl);
342 CSYNC();
343 /*kgdb_show_info();*/
344 }
345}
346
347void kgdb_disable_hw_debug(struct pt_regs *regs)
348{
349 /* Disable hardware debugging while we are in kgdb */
350 bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1);
351 CSYNC();
352}
353
354void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code)
355{
356 /* Master processor is completely in the debugger */
357 gdb_bf533vector = eVector;
358 gdb_bf533errcode = err_code;
359}
360
361int kgdb_arch_handle_exception(int exceptionVector, int signo,
362 int err_code, char *remcom_in_buffer,
363 char *remcom_out_buffer,
364 struct pt_regs *linux_regs)
365{
366 long addr;
367 long breakno;
368 char *ptr;
369 int newPC;
370 int wp_status;
371
372 switch (remcom_in_buffer[0]) {
373 case 'c':
374 case 's':
375 if (kgdb_contthread && kgdb_contthread != current) {
376 strcpy(remcom_out_buffer, "E00");
377 break;
378 }
379
380 kgdb_contthread = NULL;
381
382 /* try to read optional parameter, pc unchanged if no parm */
383 ptr = &remcom_in_buffer[1];
384 if (kgdb_hex2long(&ptr, &addr)) {
385 linux_regs->retx = addr;
386 }
387 newPC = linux_regs->retx;
388
389 /* clear the trace bit */
390 linux_regs->syscfg &= 0xfffffffe;
391
392 /* set the trace bit if we're stepping */
393 if (remcom_in_buffer[0] == 's') {
394 linux_regs->syscfg |= 0x1;
395 debugger_step = 1;
396 }
397
398 wp_status = bfin_read_WPSTAT();
399 CSYNC();
400
401 if (exceptionVector == VEC_WATCH) {
402 for (breakno = 0; breakno < 6; ++breakno) {
403 if (wp_status & (1 << breakno)) {
404 breakinfo->skip = 1;
405 break;
406 }
407 }
408 }
409 kgdb_correct_hw_break();
410
411 bfin_write_WPSTAT(0);
412
413 return 0;
414 } /* switch */
415 return -1; /* this means that we do not want to exit from the handler */
416}
417
418struct kgdb_arch arch_kgdb_ops = {
419 .gdb_bpt_instr = {0xa1},
420 .flags = KGDB_HW_BREAKPOINT,
421};
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 372f756f1ad9..8b9fe29d03f4 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -165,8 +165,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
165 165
166 for (s = sechdrs; s < sechdrs_end; ++s) { 166 for (s = sechdrs; s < sechdrs_end; ++s) {
167 if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || 167 if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
168 ((strcmp(".text", secstrings + s->sh_name)==0) && 168 ((strcmp(".text", secstrings + s->sh_name) == 0) &&
169 (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { 169 (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
170 mod->arch.text_l1 = s; 170 mod->arch.text_l1 = s;
171 dest = l1_inst_sram_alloc(s->sh_size); 171 dest = l1_inst_sram_alloc(s->sh_size);
172 if (dest == NULL) { 172 if (dest == NULL) {
@@ -179,9 +179,9 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
179 s->sh_flags &= ~SHF_ALLOC; 179 s->sh_flags &= ~SHF_ALLOC;
180 s->sh_addr = (unsigned long)dest; 180 s->sh_addr = (unsigned long)dest;
181 } 181 }
182 if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)|| 182 if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
183 ((strcmp(".data", secstrings + s->sh_name)==0) && 183 ((strcmp(".data", secstrings + s->sh_name) == 0) &&
184 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { 184 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
185 mod->arch.data_a_l1 = s; 185 mod->arch.data_a_l1 = s;
186 dest = l1_data_sram_alloc(s->sh_size); 186 dest = l1_data_sram_alloc(s->sh_size);
187 if (dest == NULL) { 187 if (dest == NULL) {
@@ -195,8 +195,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
195 s->sh_addr = (unsigned long)dest; 195 s->sh_addr = (unsigned long)dest;
196 } 196 }
197 if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || 197 if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
198 ((strcmp(".bss", secstrings + s->sh_name)==0) && 198 ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
199 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { 199 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
200 mod->arch.bss_a_l1 = s; 200 mod->arch.bss_a_l1 = s;
201 dest = l1_data_sram_alloc(s->sh_size); 201 dest = l1_data_sram_alloc(s->sh_size);
202 if (dest == NULL) { 202 if (dest == NULL) {
@@ -326,7 +326,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
326 pr_debug("before %x after %x\n", *location16, 326 pr_debug("before %x after %x\n", *location16,
327 (value & 0xffff)); 327 (value & 0xffff));
328 tmp = (value & 0xffff); 328 tmp = (value & 0xffff);
329 if((unsigned long)location16 >= L1_CODE_START) { 329 if ((unsigned long)location16 >= L1_CODE_START) {
330 dma_memcpy(location16, &tmp, 2); 330 dma_memcpy(location16, &tmp, 2);
331 } else 331 } else
332 *location16 = tmp; 332 *location16 = tmp;
@@ -335,7 +335,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
335 pr_debug("before %x after %x\n", *location16, 335 pr_debug("before %x after %x\n", *location16,
336 ((value >> 16) & 0xffff)); 336 ((value >> 16) & 0xffff));
337 tmp = ((value >> 16) & 0xffff); 337 tmp = ((value >> 16) & 0xffff);
338 if((unsigned long)location16 >= L1_CODE_START) { 338 if ((unsigned long)location16 >= L1_CODE_START) {
339 dma_memcpy(location16, &tmp, 2); 339 dma_memcpy(location16, &tmp, 2);
340 } else 340 } else
341 *location16 = tmp; 341 *location16 = tmp;
@@ -404,8 +404,8 @@ module_finalize(const Elf_Ehdr * hdr,
404 continue; 404 continue;
405 405
406 if ((sechdrs[i].sh_type == SHT_RELA) && 406 if ((sechdrs[i].sh_type == SHT_RELA) &&
407 ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)|| 407 ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
408 ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && 408 ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
409 (hdr->e_flags & FLG_CODE_IN_L1)))) { 409 (hdr->e_flags & FLG_CODE_IN_L1)))) {
410 apply_relocate_add((Elf_Shdr *) sechdrs, strtab, 410 apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
411 symindex, i, mod); 411 symindex, i, mod);
@@ -417,13 +417,13 @@ module_finalize(const Elf_Ehdr * hdr,
417void module_arch_cleanup(struct module *mod) 417void module_arch_cleanup(struct module *mod)
418{ 418{
419 if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr)) 419 if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
420 l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr); 420 l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
421 if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr)) 421 if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
422 l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr); 422 l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
423 if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr)) 423 if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
424 l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr); 424 l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
425 if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr)) 425 if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
426 l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr); 426 l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
427 if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr)) 427 if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
428 l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr); 428 l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
429} 429}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 3eff7439d8d3..5a51dd6ab280 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -32,9 +32,10 @@
32#include <linux/unistd.h> 32#include <linux/unistd.h>
33#include <linux/user.h> 33#include <linux/user.h>
34#include <linux/a.out.h> 34#include <linux/a.out.h>
35#include <linux/uaccess.h>
35 36
36#include <asm/blackfin.h> 37#include <asm/blackfin.h>
37#include <asm/uaccess.h> 38#include <asm/fixed_code.h>
38 39
39#define LED_ON 0 40#define LED_ON 0
40#define LED_OFF 1 41#define LED_OFF 1
@@ -173,8 +174,8 @@ void show_regs(struct pt_regs *regs)
173 printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", 174 printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
174 regs->r4, regs->r5, regs->r6, regs->r7); 175 regs->r4, regs->r5, regs->r6, regs->r7);
175 176
176 if (!(regs->ipend)) 177 if (!regs->ipend)
177 printk("USP: %08lx\n", rdusp()); 178 printk(KERN_NOTICE "USP: %08lx\n", rdusp());
178} 179}
179 180
180/* Fill in the fpu structure for a core dump. */ 181/* Fill in the fpu structure for a core dump. */
@@ -322,7 +323,7 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp)
322 goto out; 323 goto out;
323 error = do_execve(filename, argv, envp, regs); 324 error = do_execve(filename, argv, envp, regs);
324 putname(filename); 325 putname(filename);
325 out: 326 out:
326 unlock_kernel(); 327 unlock_kernel();
327 return error; 328 return error;
328} 329}
@@ -350,13 +351,77 @@ unsigned long get_wchan(struct task_struct *p)
350 return 0; 351 return 0;
351} 352}
352 353
354void finish_atomic_sections (struct pt_regs *regs)
355{
356 if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
357 return;
358
359 switch (regs->pc) {
360 case ATOMIC_XCHG32 + 2:
361 put_user(regs->r1, (int *)regs->p0);
362 regs->pc += 2;
363 break;
364
365 case ATOMIC_CAS32 + 2:
366 case ATOMIC_CAS32 + 4:
367 if (regs->r0 == regs->r1)
368 put_user(regs->r2, (int *)regs->p0);
369 regs->pc = ATOMIC_CAS32 + 8;
370 break;
371 case ATOMIC_CAS32 + 6:
372 put_user(regs->r2, (int *)regs->p0);
373 regs->pc += 2;
374 break;
375
376 case ATOMIC_ADD32 + 2:
377 regs->r0 = regs->r1 + regs->r0;
378 /* fall through */
379 case ATOMIC_ADD32 + 4:
380 put_user(regs->r0, (int *)regs->p0);
381 regs->pc = ATOMIC_ADD32 + 6;
382 break;
383
384 case ATOMIC_SUB32 + 2:
385 regs->r0 = regs->r1 - regs->r0;
386 /* fall through */
387 case ATOMIC_SUB32 + 4:
388 put_user(regs->r0, (int *)regs->p0);
389 regs->pc = ATOMIC_SUB32 + 6;
390 break;
391
392 case ATOMIC_IOR32 + 2:
393 regs->r0 = regs->r1 | regs->r0;
394 /* fall through */
395 case ATOMIC_IOR32 + 4:
396 put_user(regs->r0, (int *)regs->p0);
397 regs->pc = ATOMIC_IOR32 + 6;
398 break;
399
400 case ATOMIC_AND32 + 2:
401 regs->r0 = regs->r1 & regs->r0;
402 /* fall through */
403 case ATOMIC_AND32 + 4:
404 put_user(regs->r0, (int *)regs->p0);
405 regs->pc = ATOMIC_AND32 + 6;
406 break;
407
408 case ATOMIC_XOR32 + 2:
409 regs->r0 = regs->r1 ^ regs->r0;
410 /* fall through */
411 case ATOMIC_XOR32 + 4:
412 put_user(regs->r0, (int *)regs->p0);
413 regs->pc = ATOMIC_XOR32 + 6;
414 break;
415 }
416}
417
353#if defined(CONFIG_ACCESS_CHECK) 418#if defined(CONFIG_ACCESS_CHECK)
354int _access_ok(unsigned long addr, unsigned long size) 419int _access_ok(unsigned long addr, unsigned long size)
355{ 420{
356 421
357 if (addr > (addr + size)) 422 if (addr > (addr + size))
358 return 0; 423 return 0;
359 if (segment_eq(get_fs(),KERNEL_DS)) 424 if (segment_eq(get_fs(), KERNEL_DS))
360 return 1; 425 return 1;
361#ifdef CONFIG_MTD_UCLINUX 426#ifdef CONFIG_MTD_UCLINUX
362 if (addr >= memory_start && (addr + size) <= memory_end) 427 if (addr >= memory_start && (addr + size) <= memory_end)
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index e718bb4a1ef0..ed800c7456dd 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -36,8 +36,8 @@
36#include <linux/ptrace.h> 36#include <linux/ptrace.h>
37#include <linux/user.h> 37#include <linux/user.h>
38#include <linux/signal.h> 38#include <linux/signal.h>
39#include <linux/uaccess.h>
39 40
40#include <asm/uaccess.h>
41#include <asm/page.h> 41#include <asm/page.h>
42#include <asm/pgtable.h> 42#include <asm/pgtable.h>
43#include <asm/system.h> 43#include <asm/system.h>
@@ -122,7 +122,7 @@ static inline long get_reg(struct task_struct *task, int regno)
122static inline int 122static inline int
123put_reg(struct task_struct *task, int regno, unsigned long data) 123put_reg(struct task_struct *task, int regno, unsigned long data)
124{ 124{
125 char * reg_ptr; 125 char *reg_ptr;
126 126
127 struct pt_regs *regs = 127 struct pt_regs *regs =
128 (struct pt_regs *)((unsigned long)task_stack_page(task) + 128 (struct pt_regs *)((unsigned long)task_stack_page(task) +
@@ -146,7 +146,7 @@ put_reg(struct task_struct *task, int regno, unsigned long data)
146 break; 146 break;
147 default: 147 default:
148 if (regno <= 216) 148 if (regno <= 216)
149 *(long *)(reg_ptr + regno) = data; 149 *(long *)(reg_ptr + regno) = data;
150 } 150 }
151 return 0; 151 return 0;
152} 152}
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 83060f98d15d..f59dcee7bae3 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -42,6 +42,7 @@
42#include <asm/cacheflush.h> 42#include <asm/cacheflush.h>
43#include <asm/blackfin.h> 43#include <asm/blackfin.h>
44#include <asm/cplbinit.h> 44#include <asm/cplbinit.h>
45#include <asm/fixed_code.h>
45 46
46u16 _bfin_swrst; 47u16 _bfin_swrst;
47 48
@@ -63,10 +64,6 @@ EXPORT_SYMBOL(mtd_size);
63 64
64char __initdata command_line[COMMAND_LINE_SIZE]; 65char __initdata command_line[COMMAND_LINE_SIZE];
65 66
66#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
67static void generate_cpl_tables(void);
68#endif
69
70void __init bf53x_cache_init(void) 67void __init bf53x_cache_init(void)
71{ 68{
72#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 69#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
@@ -197,6 +194,17 @@ void __init setup_arch(char **cmdline_p)
197 /* this give a chance to get printk() working before crash. */ 194 /* this give a chance to get printk() working before crash. */
198#endif 195#endif
199 196
197 printk(KERN_INFO "Hardware Trace ");
198 if (bfin_read_TBUFCTL() & 0x1 )
199 printk("Active ");
200 else
201 printk("Off ");
202 if (bfin_read_TBUFCTL() & 0x2)
203 printk("and Enabled\n");
204 else
205 printk("and Disabled\n");
206
207
200#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 208#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
201 /* we need to initialize the Flashrom device here since we might 209 /* we need to initialize the Flashrom device here since we might
202 * do things with flash early on in the boot 210 * do things with flash early on in the boot
@@ -354,15 +362,15 @@ void __init setup_arch(char **cmdline_p)
354 , _stext, _etext, 362 , _stext, _etext,
355 __start_rodata, __end_rodata, 363 __start_rodata, __end_rodata,
356 _sdata, _edata, 364 _sdata, _edata,
357 (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), 365 (void *)&init_thread_union, (void *)((int)(&init_thread_union) + 0x2000),
358 __init_begin, __init_end, 366 __init_begin, __init_end,
359 __bss_start, __bss_stop, 367 __bss_start, __bss_stop,
360 (void*)_ramstart, (void*)memory_end 368 (void *)_ramstart, (void *)memory_end
361#ifdef CONFIG_MTD_UCLINUX 369#ifdef CONFIG_MTD_UCLINUX
362 , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) 370 , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size)
363#endif 371#endif
364#if DMA_UNCACHED_REGION > 0 372#if DMA_UNCACHED_REGION > 0
365 , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) 373 , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend)
366#endif 374#endif
367 ); 375 );
368 376
@@ -388,11 +396,11 @@ void __init setup_arch(char **cmdline_p)
388 /* check the size of the l1 area */ 396 /* check the size of the l1 area */
389 l1_length = _etext_l1 - _stext_l1; 397 l1_length = _etext_l1 - _stext_l1;
390 if (l1_length > L1_CODE_LENGTH) 398 if (l1_length > L1_CODE_LENGTH)
391 panic("L1 memory overflow\n"); 399 panic("L1 code memory overflow\n");
392 400
393 l1_length = _ebss_l1 - _sdata_l1; 401 l1_length = _ebss_l1 - _sdata_l1;
394 if (l1_length > L1_DATA_A_LENGTH) 402 if (l1_length > L1_DATA_A_LENGTH)
395 panic("L1 memory overflow\n"); 403 panic("L1 data memory overflow\n");
396 404
397#ifdef BF561_FAMILY 405#ifdef BF561_FAMILY
398 _bfin_swrst = bfin_read_SICA_SWRST(); 406 _bfin_swrst = bfin_read_SICA_SWRST();
@@ -400,10 +408,28 @@ void __init setup_arch(char **cmdline_p)
400 _bfin_swrst = bfin_read_SWRST(); 408 _bfin_swrst = bfin_read_SWRST();
401#endif 409#endif
402 410
403 bf53x_cache_init(); 411 /* Copy atomic sequences to their fixed location, and sanity check that
412 these locations are the ones that we advertise to userspace. */
413 memcpy((void *)FIXED_CODE_START, &fixed_code_start,
414 FIXED_CODE_END - FIXED_CODE_START);
415 BUG_ON((char *)&sigreturn_stub - (char *)&fixed_code_start
416 != SIGRETURN_STUB - FIXED_CODE_START);
417 BUG_ON((char *)&atomic_xchg32 - (char *)&fixed_code_start
418 != ATOMIC_XCHG32 - FIXED_CODE_START);
419 BUG_ON((char *)&atomic_cas32 - (char *)&fixed_code_start
420 != ATOMIC_CAS32 - FIXED_CODE_START);
421 BUG_ON((char *)&atomic_add32 - (char *)&fixed_code_start
422 != ATOMIC_ADD32 - FIXED_CODE_START);
423 BUG_ON((char *)&atomic_sub32 - (char *)&fixed_code_start
424 != ATOMIC_SUB32 - FIXED_CODE_START);
425 BUG_ON((char *)&atomic_ior32 - (char *)&fixed_code_start
426 != ATOMIC_IOR32 - FIXED_CODE_START);
427 BUG_ON((char *)&atomic_and32 - (char *)&fixed_code_start
428 != ATOMIC_AND32 - FIXED_CODE_START);
429 BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start
430 != ATOMIC_XOR32 - FIXED_CODE_START);
404 431
405 printk(KERN_INFO "Hardware Trace Enabled\n"); 432 bf53x_cache_init();
406 bfin_write_TBUFCTL(0x03);
407} 433}
408 434
409static int __init topology_init(void) 435static int __init topology_init(void)
@@ -421,286 +447,6 @@ static int __init topology_init(void)
421 447
422subsys_initcall(topology_init); 448subsys_initcall(topology_init);
423 449
424#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
425static u16 __init lock_kernel_check(u32 start, u32 end)
426{
427 if ((start <= (u32) _stext && end >= (u32) _end)
428 || (start >= (u32) _stext && end <= (u32) _end))
429 return IN_KERNEL;
430 return 0;
431}
432
433static unsigned short __init
434fill_cplbtab(struct cplb_tab *table,
435 unsigned long start, unsigned long end,
436 unsigned long block_size, unsigned long cplb_data)
437{
438 int i;
439
440 switch (block_size) {
441 case SIZE_4M:
442 i = 3;
443 break;
444 case SIZE_1M:
445 i = 2;
446 break;
447 case SIZE_4K:
448 i = 1;
449 break;
450 case SIZE_1K:
451 default:
452 i = 0;
453 break;
454 }
455
456 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
457
458 while ((start < end) && (table->pos < table->size)) {
459
460 table->tab[table->pos++] = start;
461
462 if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
463 table->tab[table->pos++] =
464 cplb_data | CPLB_LOCK | CPLB_DIRTY;
465 else
466 table->tab[table->pos++] = cplb_data;
467
468 start += block_size;
469 }
470 return 0;
471}
472
473static unsigned short __init
474close_cplbtab(struct cplb_tab *table)
475{
476
477 while (table->pos < table->size) {
478
479 table->tab[table->pos++] = 0;
480 table->tab[table->pos++] = 0; /* !CPLB_VALID */
481 }
482 return 0;
483}
484
485/* helper function */
486static void __fill_code_cplbtab(struct cplb_tab *t, int i,
487 u32 a_start, u32 a_end)
488{
489 if (cplb_data[i].psize) {
490 fill_cplbtab(t,
491 cplb_data[i].start,
492 cplb_data[i].end,
493 cplb_data[i].psize,
494 cplb_data[i].i_conf);
495 } else {
496#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
497 if (i == SDRAM_KERN) {
498 fill_cplbtab(t,
499 cplb_data[i].start,
500 cplb_data[i].end,
501 SIZE_4M,
502 cplb_data[i].i_conf);
503 } else {
504#endif
505 fill_cplbtab(t,
506 cplb_data[i].start,
507 a_start,
508 SIZE_1M,
509 cplb_data[i].i_conf);
510 fill_cplbtab(t,
511 a_start,
512 a_end,
513 SIZE_4M,
514 cplb_data[i].i_conf);
515 fill_cplbtab(t, a_end,
516 cplb_data[i].end,
517 SIZE_1M,
518 cplb_data[i].i_conf);
519 }
520 }
521}
522
523static void __fill_data_cplbtab(struct cplb_tab *t, int i,
524 u32 a_start, u32 a_end)
525{
526 if (cplb_data[i].psize) {
527 fill_cplbtab(t,
528 cplb_data[i].start,
529 cplb_data[i].end,
530 cplb_data[i].psize,
531 cplb_data[i].d_conf);
532 } else {
533 fill_cplbtab(t,
534 cplb_data[i].start,
535 a_start, SIZE_1M,
536 cplb_data[i].d_conf);
537 fill_cplbtab(t, a_start,
538 a_end, SIZE_4M,
539 cplb_data[i].d_conf);
540 fill_cplbtab(t, a_end,
541 cplb_data[i].end,
542 SIZE_1M,
543 cplb_data[i].d_conf);
544 }
545}
546static void __init generate_cpl_tables(void)
547{
548
549 u16 i, j, process;
550 u32 a_start, a_end, as, ae, as_1m;
551
552 struct cplb_tab *t_i = NULL;
553 struct cplb_tab *t_d = NULL;
554 struct s_cplb cplb;
555
556 cplb.init_i.size = MAX_CPLBS;
557 cplb.init_d.size = MAX_CPLBS;
558 cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
559 cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
560
561 cplb.init_i.pos = 0;
562 cplb.init_d.pos = 0;
563 cplb.switch_i.pos = 0;
564 cplb.switch_d.pos = 0;
565
566 cplb.init_i.tab = icplb_table;
567 cplb.init_d.tab = dcplb_table;
568 cplb.switch_i.tab = ipdt_table;
569 cplb.switch_d.tab = dpdt_table;
570
571 cplb_data[SDRAM_KERN].end = memory_end;
572
573#ifdef CONFIG_MTD_UCLINUX
574 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
575 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
576 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
577# if defined(CONFIG_ROMFS_FS)
578 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
579
580 /*
581 * The ROMFS_FS size is often not multiple of 1MB.
582 * This can cause multiple CPLB sets covering the same memory area.
583 * This will then cause multiple CPLB hit exceptions.
584 * Workaround: We ensure a contiguous memory area by extending the kernel
585 * memory section over the mtd section.
586 * For ROMFS_FS memory must be covered with ICPLBs anyways.
587 * So there is no difference between kernel and mtd memory setup.
588 */
589
590 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
591 cplb_data[SDRAM_RAM_MTD].valid = 0;
592
593# endif
594#else
595 cplb_data[SDRAM_RAM_MTD].valid = 0;
596#endif
597
598 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
599 cplb_data[SDRAM_DMAZ].end = _ramend;
600
601 cplb_data[RES_MEM].start = _ramend;
602 cplb_data[RES_MEM].end = physical_mem_end;
603
604 if (reserved_mem_dcache_on)
605 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
606 else
607 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
608
609 if (reserved_mem_icache_on)
610 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
611 else
612 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
613
614 for (i = ZERO_P; i <= L2_MEM; i++) {
615 if (!cplb_data[i].valid)
616 continue;
617
618 as_1m = cplb_data[i].start % SIZE_1M;
619
620 /*
621 * We need to make sure all sections are properly 1M aligned
622 * However between Kernel Memory and the Kernel mtd section,
623 * depending on the rootfs size, there can be overlapping
624 * memory areas.
625 */
626
627 if (as_1m && i != L1I_MEM && i != L1D_MEM) {
628#ifdef CONFIG_MTD_UCLINUX
629 if (i == SDRAM_RAM_MTD) {
630 if ((cplb_data[SDRAM_KERN].end + 1) >
631 cplb_data[SDRAM_RAM_MTD].start)
632 cplb_data[SDRAM_RAM_MTD].start =
633 (cplb_data[i].start &
634 (-2*SIZE_1M)) + SIZE_1M;
635 else
636 cplb_data[SDRAM_RAM_MTD].start =
637 (cplb_data[i].start &
638 (-2*SIZE_1M));
639 } else
640#endif
641 printk(KERN_WARNING
642 "Unaligned Start of %s at 0x%X\n",
643 cplb_data[i].name, cplb_data[i].start);
644 }
645
646 as = cplb_data[i].start % SIZE_4M;
647 ae = cplb_data[i].end % SIZE_4M;
648
649 if (as)
650 a_start = cplb_data[i].start + (SIZE_4M - (as));
651 else
652 a_start = cplb_data[i].start;
653
654 a_end = cplb_data[i].end - ae;
655
656 for (j = INITIAL_T; j <= SWITCH_T; j++) {
657
658 switch (j) {
659 case INITIAL_T:
660 if (cplb_data[i].attr & INITIAL_T) {
661 t_i = &cplb.init_i;
662 t_d = &cplb.init_d;
663 process = 1;
664 } else
665 process = 0;
666 break;
667 case SWITCH_T:
668 if (cplb_data[i].attr & SWITCH_T) {
669 t_i = &cplb.switch_i;
670 t_d = &cplb.switch_d;
671 process = 1;
672 } else
673 process = 0;
674 break;
675 default:
676 process = 0;
677 break;
678 }
679
680 if (!process)
681 continue;
682 if (cplb_data[i].attr & I_CPLB)
683 __fill_code_cplbtab(t_i, i, a_start, a_end);
684
685 if (cplb_data[i].attr & D_CPLB)
686 __fill_data_cplbtab(t_d, i, a_start, a_end);
687 }
688 }
689
690/* close tables */
691
692 close_cplbtab(&cplb.init_i);
693 close_cplbtab(&cplb.init_d);
694
695 cplb.init_i.tab[cplb.init_i.pos] = -1;
696 cplb.init_d.tab[cplb.init_d.pos] = -1;
697 cplb.switch_i.tab[cplb.switch_i.pos] = -1;
698 cplb.switch_d.tab[cplb.switch_d.pos] = -1;
699
700}
701
702#endif
703
704static u_long get_vco(void) 450static u_long get_vco(void)
705{ 451{
706 u_long msel; 452 u_long msel;
@@ -730,7 +476,6 @@ u_long get_cclk(void)
730 return get_vco() / ssel; 476 return get_vco() / ssel;
731 return get_vco() >> csel; 477 return get_vco() >> csel;
732} 478}
733
734EXPORT_SYMBOL(get_cclk); 479EXPORT_SYMBOL(get_cclk);
735 480
736/* Get the System clock */ 481/* Get the System clock */
@@ -749,7 +494,6 @@ u_long get_sclk(void)
749 494
750 return get_vco() / ssel; 495 return get_vco() / ssel;
751} 496}
752
753EXPORT_SYMBOL(get_sclk); 497EXPORT_SYMBOL(get_sclk);
754 498
755/* 499/*
@@ -804,23 +548,23 @@ static int show_cpuinfo(struct seq_file *m, void *v)
804 seq_printf(m, "D-CACHE:\tOFF\n"); 548 seq_printf(m, "D-CACHE:\tOFF\n");
805 549
806 550
807 switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { 551 switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
808 case ACACHE_BSRAM: 552 case ACACHE_BSRAM:
809 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); 553 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
810 dcache_size = 16; 554 dcache_size = 16;
811 dsup_banks = 1; 555 dsup_banks = 1;
812 break; 556 break;
813 case ACACHE_BCACHE: 557 case ACACHE_BCACHE:
814 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); 558 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
815 dcache_size = 32; 559 dcache_size = 32;
816 dsup_banks = 2; 560 dsup_banks = 2;
817 break; 561 break;
818 case ASRAM_BSRAM: 562 case ASRAM_BSRAM:
819 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); 563 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
820 dcache_size = 0; 564 dcache_size = 0;
821 dsup_banks = 0; 565 dsup_banks = 0;
822 break; 566 break;
823 default: 567 default:
824 break; 568 break;
825 } 569 }
826 570
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 316e65c3439d..5564c9588aa8 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -34,8 +34,8 @@
34#include <linux/personality.h> 34#include <linux/personality.h>
35#include <linux/binfmts.h> 35#include <linux/binfmts.h>
36#include <linux/freezer.h> 36#include <linux/freezer.h>
37#include <linux/uaccess.h>
37 38
38#include <asm/uaccess.h>
39#include <asm/cacheflush.h> 39#include <asm/cacheflush.h>
40#include <asm/ucontext.h> 40#include <asm/ucontext.h>
41 41
@@ -124,7 +124,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
124 124
125 return r0; 125 return r0;
126 126
127 badframe: 127 badframe:
128 force_sig(SIGSEGV, current); 128 force_sig(SIGSEGV, current);
129 return 0; 129 return 0;
130} 130}
@@ -239,7 +239,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
239 239
240 return 0; 240 return 0;
241 241
242 give_sigsegv: 242 give_sigsegv:
243 if (sig == SIGSEGV) 243 if (sig == SIGSEGV)
244 ka->sa.sa_handler = SIG_DFL; 244 ka->sa.sa_handler = SIG_DFL;
245 force_sig(SIGSEGV, current); 245 force_sig(SIGSEGV, current);
@@ -263,7 +263,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
263 } 263 }
264 /* fallthrough */ 264 /* fallthrough */
265 case -ERESTARTNOINTR: 265 case -ERESTARTNOINTR:
266 do_restart: 266 do_restart:
267 regs->p0 = regs->orig_p0; 267 regs->p0 = regs->orig_p0;
268 regs->r0 = regs->orig_r0; 268 regs->r0 = regs->orig_r0;
269 regs->pc -= 2; 269 regs->pc -= 2;
@@ -341,7 +341,7 @@ asmlinkage void do_signal(struct pt_regs *regs)
341 return; 341 return;
342 } 342 }
343 343
344no_signal: 344 no_signal:
345 /* Did we come from a system call? */ 345 /* Did we come from a system call? */
346 if (regs->orig_p0 >= 0) 346 if (regs->orig_p0 >= 0)
347 /* Restart the system call - no handlers present */ 347 /* Restart the system call - no handlers present */
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index f436e6743f5a..f5e1ae3d1705 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -37,12 +37,12 @@
37#include <linux/syscalls.h> 37#include <linux/syscalls.h>
38#include <linux/mman.h> 38#include <linux/mman.h>
39#include <linux/file.h> 39#include <linux/file.h>
40#include <linux/uaccess.h>
41#include <linux/ipc.h>
42#include <linux/unistd.h>
40 43
41#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
42#include <asm/uaccess.h>
43#include <asm/ipc.h>
44#include <asm/dma.h> 45#include <asm/dma.h>
45#include <asm/unistd.h>
46 46
47/* 47/*
48 * sys_pipe() is the normal C calling standard for creating 48 * sys_pipe() is the normal C calling standard for creating
@@ -83,7 +83,7 @@ do_mmap2(unsigned long addr, unsigned long len,
83 83
84 if (file) 84 if (file)
85 fput(file); 85 fput(file);
86 out: 86 out:
87 return error; 87 return error;
88} 88}
89 89
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index f578176b6d92..beef057bd1dc 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -87,7 +87,7 @@ void __init init_leds(void)
87static inline void do_leds(void) 87static inline void do_leds(void)
88{ 88{
89 static unsigned int count = 50; 89 static unsigned int count = 50;
90 static int flag = 0; 90 static int flag;
91 unsigned short tmp = 0; 91 unsigned short tmp = 0;
92 92
93 if (--count == 0) { 93 if (--count == 0) {
@@ -200,7 +200,7 @@ irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text));
200irqreturn_t timer_interrupt(int irq, void *dummy) 200irqreturn_t timer_interrupt(int irq, void *dummy)
201{ 201{
202 /* last time the cmos clock got updated */ 202 /* last time the cmos clock got updated */
203 static long last_rtc_update = 0; 203 static long last_rtc_update;
204 204
205 write_seqlock(&xtime_lock); 205 write_seqlock(&xtime_lock);
206 206
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 56058b0b6d4a..3909f5b35536 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -27,15 +27,15 @@
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 28 */
29 29
30#include <asm/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/interrupt.h>
32#include <linux/module.h>
33#include <linux/kallsyms.h>
31#include <asm/traps.h> 34#include <asm/traps.h>
32#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
33#include <asm/blackfin.h> 36#include <asm/blackfin.h>
34#include <asm/uaccess.h>
35#include <asm/irq_handler.h> 37#include <asm/irq_handler.h>
36#include <linux/interrupt.h> 38#include <asm/trace.h>
37#include <linux/module.h>
38#include <linux/kallsyms.h>
39 39
40#ifdef CONFIG_KGDB 40#ifdef CONFIG_KGDB
41# include <linux/debugger.h> 41# include <linux/debugger.h>
@@ -76,7 +76,7 @@ static int printk_address(unsigned long address)
76 if (!modname) 76 if (!modname)
77 modname = delim = ""; 77 modname = delim = "";
78 return printk("<0x%p> { %s%s%s%s + 0x%lx }", 78 return printk("<0x%p> { %s%s%s%s + 0x%lx }",
79 (void*)address, delim, modname, delim, symname, 79 (void *)address, delim, modname, delim, symname,
80 (unsigned long)offset); 80 (unsigned long)offset);
81 81
82 } 82 }
@@ -119,7 +119,7 @@ static int printk_address(unsigned long address)
119 119
120 write_unlock_irq(&tasklist_lock); 120 write_unlock_irq(&tasklist_lock);
121 return printk("<0x%p> [ %s + 0x%lx ]", 121 return printk("<0x%p> [ %s + 0x%lx ]",
122 (void*)address, name, offset); 122 (void *)address, name, offset);
123 } 123 }
124 124
125 vml = vml->next; 125 vml = vml->next;
@@ -128,19 +128,9 @@ static int printk_address(unsigned long address)
128 write_unlock_irq(&tasklist_lock); 128 write_unlock_irq(&tasklist_lock);
129 129
130 /* we were unable to find this address anywhere */ 130 /* we were unable to find this address anywhere */
131 return printk("[<0x%p>]", (void*)address); 131 return printk("[<0x%p>]", (void *)address);
132} 132}
133 133
134#define trace_buffer_save(x) \
135 do { \
136 (x) = bfin_read_TBUFCTL(); \
137 bfin_write_TBUFCTL((x) & ~TBUFEN); \
138 } while (0)
139#define trace_buffer_restore(x) \
140 do { \
141 bfin_write_TBUFCTL((x)); \
142 } while (0)
143
144asmlinkage void trap_c(struct pt_regs *fp) 134asmlinkage void trap_c(struct pt_regs *fp)
145{ 135{
146 int j, sig = 0; 136 int j, sig = 0;
@@ -203,15 +193,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
203#else 193#else
204 /* 0x02 - User Defined, Caught by default */ 194 /* 0x02 - User Defined, Caught by default */
205#endif 195#endif
206 /* 0x03 - Atomic test and set */ 196 /* 0x03 - User Defined, userspace stack overflow */
207 case VEC_EXCPT03: 197 case VEC_EXCPT03:
208 info.si_code = SEGV_STACKFLOW; 198 info.si_code = SEGV_STACKFLOW;
209 sig = SIGSEGV; 199 sig = SIGSEGV;
210 printk(KERN_EMERG EXC_0x03); 200 printk(KERN_EMERG EXC_0x03);
211 CHK_DEBUGGER_TRAP(); 201 CHK_DEBUGGER_TRAP();
212 break; 202 break;
213 /* 0x04 - spinlock - handled by _ex_spinlock, 203 /* 0x04 - User Defined, Caught by default */
214 getting here is an error */
215 /* 0x05 - User Defined, Caught by default */ 204 /* 0x05 - User Defined, Caught by default */
216 /* 0x06 - User Defined, Caught by default */ 205 /* 0x06 - User Defined, Caught by default */
217 /* 0x07 - User Defined, Caught by default */ 206 /* 0x07 - User Defined, Caught by default */
@@ -547,29 +536,28 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
547 printk(KERN_EMERG "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 536 printk(KERN_EMERG "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
548 KERN_EMERG "BSS = 0x%p-0x%p USER-STACK = 0x%p\n" 537 KERN_EMERG "BSS = 0x%p-0x%p USER-STACK = 0x%p\n"
549 KERN_EMERG "\n", 538 KERN_EMERG "\n",
550 (void*)current->mm->start_code, 539 (void *)current->mm->start_code,
551 (void*)current->mm->end_code, 540 (void *)current->mm->end_code,
552 (void*)current->mm->start_data, 541 (void *)current->mm->start_data,
553 (void*)current->mm->end_data, 542 (void *)current->mm->end_data,
554 (void*)current->mm->end_data, 543 (void *)current->mm->end_data,
555 (void*)current->mm->brk, 544 (void *)current->mm->brk,
556 (void*)current->mm->start_stack); 545 (void *)current->mm->start_stack);
557 } 546 }
558 547
559 printk(KERN_EMERG "return address: [0x%p]; contents of:", retaddr); 548 printk(KERN_EMERG "return address: [0x%p]; contents of:", retaddr);
560 if (retaddr != 0 && retaddr <= (void*)physical_mem_end 549 if (retaddr != 0 && retaddr <= (void *)physical_mem_end
561#if L1_CODE_LENGTH != 0 550#if L1_CODE_LENGTH != 0
562 /* FIXME: Copy the code out of L1 Instruction SRAM through dma 551 /* FIXME: Copy the code out of L1 Instruction SRAM through dma
563 memcpy. */ 552 memcpy. */
564 && !(retaddr >= (void*)L1_CODE_START 553 && !(retaddr >= (void *)L1_CODE_START
565 && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH)) 554 && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
566#endif 555#endif
567 ) { 556 ) {
568 int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32; 557 int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
569 unsigned short x = 0; 558 unsigned short x = 0;
570 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0 ) + 32 ; 559 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
571 i += 2) { 560 if (!(i & 0xF))
572 if ( !(i & 0xF) )
573 printk(KERN_EMERG "\n" KERN_EMERG 561 printk(KERN_EMERG "\n" KERN_EMERG
574 "0x%08x: ", i); 562 "0x%08x: ", i);
575 563
@@ -588,7 +576,7 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
588 " The rest of this error" 576 " The rest of this error"
589 " is meanless\n"); 577 " is meanless\n");
590#endif 578#endif
591 if ( i == (unsigned int)retaddr ) 579 if (i == (unsigned int)retaddr)
592 printk("[%04x]", x); 580 printk("[%04x]", x);
593 else 581 else
594 printk(" %04x ", x); 582 printk(" %04x ", x);
@@ -681,8 +669,8 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
681 break; 669 break;
682 } 670 }
683 671
684 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); 672 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
685 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); 673 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
686 dump_bfin_regs(fp, (void *)fp->retx); 674 dump_bfin_regs(fp, (void *)fp->retx);
687 dump_stack(); 675 dump_stack();
688 panic("Unrecoverable event\n"); 676 panic("Unrecoverable event\n");
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 1ef1e36b3957..d06f860f4790 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -31,6 +31,7 @@
31 31
32#include <asm-generic/vmlinux.lds.h> 32#include <asm-generic/vmlinux.lds.h>
33#include <asm/mem_map.h> 33#include <asm/mem_map.h>
34#include <asm/page.h>
34 35
35OUTPUT_FORMAT("elf32-bfin") 36OUTPUT_FORMAT("elf32-bfin")
36ENTRY(__start) 37ENTRY(__start)
@@ -63,8 +64,8 @@ SECTIONS
63 64
64 .data : 65 .data :
65 { 66 {
67 . = ALIGN(PAGE_SIZE);
66 __sdata = .; 68 __sdata = .;
67 . = ALIGN(0x2000);
68 *(.data.init_task) 69 *(.data.init_task)
69 DATA_DATA 70 DATA_DATA
70 CONSTRUCTORS 71 CONSTRUCTORS
@@ -72,14 +73,14 @@ SECTIONS
72 . = ALIGN(32); 73 . = ALIGN(32);
73 *(.data.cacheline_aligned) 74 *(.data.cacheline_aligned)
74 75
75 . = ALIGN(0x2000); 76 . = ALIGN(PAGE_SIZE);
76 __edata = .; 77 __edata = .;
77 } 78 }
78 79
80 . = ALIGN(PAGE_SIZE);
79 ___init_begin = .; 81 ___init_begin = .;
80 .init : 82 .init :
81 { 83 {
82 . = ALIGN(4096);
83 __sinittext = .; 84 __sinittext = .;
84 *(.init.text) 85 *(.init.text)
85 __einittext = .; 86 __einittext = .;
@@ -152,9 +153,10 @@ SECTIONS
152 __ebss_b_l1 = .; 153 __ebss_b_l1 = .;
153 } 154 }
154 155
155 ___init_end = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1); 156 . = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
157 ___init_end = ALIGN(PAGE_SIZE);
156 158
157 .bss LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1) : 159 .bss ___init_end :
158 { 160 {
159 . = ALIGN(4); 161 . = ALIGN(4);
160 ___bss_start = .; 162 ___bss_start = .;
diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c
index 2ad47c4254ba..4eeefd86907f 100644
--- a/arch/blackfin/lib/strcmp.c
+++ b/arch/blackfin/lib/strcmp.c
@@ -6,6 +6,5 @@
6 6
7int strcmp(const char *dest, const char *src) 7int strcmp(const char *dest, const char *src)
8{ 8{
9 return __inline_strcmp(dest, src); 9 return __inline_strcmp(dest, src);
10} 10}
11
diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c
index 4dc835a8a19b..534589db7256 100644
--- a/arch/blackfin/lib/strcpy.c
+++ b/arch/blackfin/lib/strcpy.c
@@ -6,6 +6,5 @@
6 6
7char *strcpy(char *dest, const char *src) 7char *strcpy(char *dest, const char *src)
8{ 8{
9 return __inline_strcpy(dest, src); 9 return __inline_strcpy(dest, src);
10} 10}
11
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
index 947bcfe3f3bb..d791f120bff7 100644
--- a/arch/blackfin/lib/strncmp.c
+++ b/arch/blackfin/lib/strncmp.c
@@ -6,6 +6,5 @@
6 6
7int strncmp(const char *cs, const char *ct, size_t count) 7int strncmp(const char *cs, const char *ct, size_t count)
8{ 8{
9 return __inline_strncmp(cs, ct, count); 9 return __inline_strncmp(cs, ct, count);
10} 10}
11
diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c
index 77a9b2e95097..1fecb5c71ffb 100644
--- a/arch/blackfin/lib/strncpy.c
+++ b/arch/blackfin/lib/strncpy.c
@@ -6,6 +6,5 @@
6 6
7char *strncpy(char *dest, const char *src, size_t n) 7char *strncpy(char *dest, const char *src, size_t n)
8{ 8{
9 return __inline_strncpy(dest, src, n); 9 return __inline_strncpy(dest, src, n);
10} 10}
11
diff --git a/arch/blackfin/mach-bf533/Makefile b/arch/blackfin/mach-bf533/Makefile
index 76d2c2b8579a..8cce1736360d 100644
--- a/arch/blackfin/mach-bf533/Makefile
+++ b/arch/blackfin/mach-bf533/Makefile
@@ -4,6 +4,6 @@
4 4
5extra-y := head.o 5extra-y := head.o
6 6
7obj-y := ints-priority.o 7obj-y := ints-priority.o dma.o
8 8
9obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o 9obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index edd31ce4f8d2..4545f363e641 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -34,7 +34,7 @@
34#include <linux/spi/spi.h> 34#include <linux/spi/spi.h>
35#include <linux/spi/flash.h> 35#include <linux/spi/flash.h>
36#include <linux/usb_isp1362.h> 36#include <linux/usb_isp1362.h>
37#include <asm/irq.h> 37#include <linux/irq.h>
38#include <asm/bfin5xx_spi.h> 38#include <asm/bfin5xx_spi.h>
39 39
40/* 40/*
@@ -51,11 +51,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
51 .size = 0x00020000, 51 .size = 0x00020000,
52 .offset = 0, 52 .offset = 0,
53 .mask_flags = MTD_CAP_ROM 53 .mask_flags = MTD_CAP_ROM
54 },{ 54 }, {
55 .name = "kernel", 55 .name = "kernel",
56 .size = 0xe0000, 56 .size = 0xe0000,
57 .offset = 0x20000 57 .offset = 0x20000
58 },{ 58 }, {
59 .name = "file system", 59 .name = "file system",
60 .size = 0x700000, 60 .size = 0x700000,
61 .offset = 0x00100000, 61 .offset = 0x00100000,
@@ -98,7 +98,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
98 .platform_data = &bfin_spi_flash_data, 98 .platform_data = &bfin_spi_flash_data,
99 .controller_data = &spi_flash_chip_info, 99 .controller_data = &spi_flash_chip_info,
100 .mode = SPI_MODE_3, 100 .mode = SPI_MODE_3,
101 },{ 101 }, {
102 .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ 102 .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
103 .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ 103 .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
104 .bus_num = 1, /* Framework bus number */ 104 .bus_num = 1, /* Framework bus number */
@@ -145,7 +145,7 @@ static struct resource smc91x_resources[] = {
145 .start = 0x20200300, 145 .start = 0x20200300,
146 .end = 0x20200300 + 16, 146 .end = 0x20200300 + 16,
147 .flags = IORESOURCE_MEM, 147 .flags = IORESOURCE_MEM,
148 },{ 148 }, {
149 .start = IRQ_PF0, 149 .start = IRQ_PF0,
150 .end = IRQ_PF0, 150 .end = IRQ_PF0,
151 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 151 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -194,11 +194,11 @@ static struct resource isp1362_hcd_resources[] = {
194 .start = 0x20308000, 194 .start = 0x20308000,
195 .end = 0x20308000, 195 .end = 0x20308000,
196 .flags = IORESOURCE_MEM, 196 .flags = IORESOURCE_MEM,
197 },{ 197 }, {
198 .start = 0x20308004, 198 .start = 0x20308004,
199 .end = 0x20308004, 199 .end = 0x20308004,
200 .flags = IORESOURCE_MEM, 200 .flags = IORESOURCE_MEM,
201 },{ 201 }, {
202 .start = IRQ_PF4, 202 .start = IRQ_PF4,
203 .end = IRQ_PF4, 203 .end = IRQ_PF4,
204 .flags = IORESOURCE_IRQ, 204 .flags = IORESOURCE_IRQ,
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 0b522d95160d..0000b8f1239c 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -35,7 +35,7 @@
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 36#include <linux/spi/flash.h>
37#include <linux/usb_isp1362.h> 37#include <linux/usb_isp1362.h>
38#include <asm/irq.h> 38#include <linux/irq.h>
39#include <asm/bfin5xx_spi.h> 39#include <asm/bfin5xx_spi.h>
40 40
41/* 41/*
@@ -61,7 +61,7 @@ static struct resource smc91x_resources[] = {
61 .start = 0x20310300, 61 .start = 0x20310300,
62 .end = 0x20310300 + 16, 62 .end = 0x20310300 + 16,
63 .flags = IORESOURCE_MEM, 63 .flags = IORESOURCE_MEM,
64 },{ 64 }, {
65 .start = IRQ_PF9, 65 .start = IRQ_PF9,
66 .end = IRQ_PF9, 66 .end = IRQ_PF9,
67 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 67 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -85,11 +85,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
85 .size = 0x00020000, 85 .size = 0x00020000,
86 .offset = 0, 86 .offset = 0,
87 .mask_flags = MTD_CAP_ROM 87 .mask_flags = MTD_CAP_ROM
88 },{ 88 }, {
89 .name = "kernel", 89 .name = "kernel",
90 .size = 0xe0000, 90 .size = 0xe0000,
91 .offset = 0x20000 91 .offset = 0x20000
92 },{ 92 }, {
93 .name = "file system", 93 .name = "file system",
94 .size = 0x700000, 94 .size = 0x700000,
95 .offset = 0x00100000, 95 .offset = 0x00100000,
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
index c0f43ccfbfb5..9bc1f0d0ab50 100644
--- a/arch/blackfin/mach-bf533/boards/generic_board.c
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -30,7 +30,7 @@
30 30
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <asm/irq.h> 33#include <linux/irq.h>
34 34
35/* 35/*
36 * Name the Board for the /proc/cpuinfo 36 * Name the Board for the /proc/cpuinfo
@@ -53,11 +53,11 @@ static struct resource smc91x_resources[] = {
53 .start = 0x20300300, 53 .start = 0x20300300,
54 .end = 0x20300300 + 16, 54 .end = 0x20300300 + 16,
55 .flags = IORESOURCE_MEM, 55 .flags = IORESOURCE_MEM,
56 },{ 56 }, {
57 .start = IRQ_PROG_INTB, 57 .start = IRQ_PROG_INTB,
58 .end = IRQ_PROG_INTB, 58 .end = IRQ_PROG_INTB,
59 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 59 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
60 },{ 60 }, {
61 /* 61 /*
62 * denotes the flag pin and is used directly if 62 * denotes the flag pin and is used directly if
63 * CONFIG_IRQCHIP_DEMUX_GPIO is defined. 63 * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 9a472fe15833..a9143c4cbdcd 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -37,7 +37,7 @@
37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
38#include <linux/usb_isp1362.h> 38#include <linux/usb_isp1362.h>
39#endif 39#endif
40#include <asm/irq.h> 40#include <linux/irq.h>
41#include <asm/bfin5xx_spi.h> 41#include <asm/bfin5xx_spi.h>
42 42
43/* 43/*
@@ -62,7 +62,7 @@ static struct resource smc91x_resources[] = {
62 .start = 0x20300300, 62 .start = 0x20300300,
63 .end = 0x20300300 + 16, 63 .end = 0x20300300 + 16,
64 .flags = IORESOURCE_MEM, 64 .flags = IORESOURCE_MEM,
65 },{ 65 }, {
66 .start = IRQ_PF7, 66 .start = IRQ_PF7,
67 .end = IRQ_PF7, 67 .end = IRQ_PF7,
68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -83,7 +83,7 @@ static struct resource net2272_bfin_resources[] = {
83 .start = 0x20300000, 83 .start = 0x20300000,
84 .end = 0x20300000 + 0x100, 84 .end = 0x20300000 + 0x100,
85 .flags = IORESOURCE_MEM, 85 .flags = IORESOURCE_MEM,
86 },{ 86 }, {
87 .start = IRQ_PF10, 87 .start = IRQ_PF10,
88 .end = IRQ_PF10, 88 .end = IRQ_PF10,
89 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 89 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -108,11 +108,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
108 .size = 0x00020000, 108 .size = 0x00020000,
109 .offset = 0, 109 .offset = 0,
110 .mask_flags = MTD_CAP_ROM 110 .mask_flags = MTD_CAP_ROM
111 },{ 111 }, {
112 .name = "kernel", 112 .name = "kernel",
113 .size = 0xe0000, 113 .size = 0xe0000,
114 .offset = 0x20000 114 .offset = 0x20000
115 },{ 115 }, {
116 .name = "file system", 116 .name = "file system",
117 .size = 0x700000, 117 .size = 0x700000,
118 .offset = 0x00100000, 118 .offset = 0x00100000,
@@ -229,19 +229,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
229 229
230#if defined(CONFIG_PBX) 230#if defined(CONFIG_PBX)
231 { 231 {
232 .modalias = "fxs-spi", 232 .modalias = "fxs-spi",
233 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ 233 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
234 .bus_num = 1, 234 .bus_num = 1,
235 .chip_select = 3, 235 .chip_select = 3,
236 .controller_data= &spi_si3xxx_chip_info, 236 .controller_data = &spi_si3xxx_chip_info,
237 .mode = SPI_MODE_3, 237 .mode = SPI_MODE_3,
238 }, 238 },
239 { 239 {
240 .modalias = "fxo-spi", 240 .modalias = "fxo-spi",
241 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ 241 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
242 .bus_num = 1, 242 .bus_num = 1,
243 .chip_select = 2, 243 .chip_select = 2,
244 .controller_data= &spi_si3xxx_chip_info, 244 .controller_data = &spi_si3xxx_chip_info,
245 .mode = SPI_MODE_3, 245 .mode = SPI_MODE_3,
246 }, 246 },
247#endif 247#endif
diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c
index 99547c4c290e..6fd9cfd0a31b 100644
--- a/arch/blackfin/mach-bf533/cpu.c
+++ b/arch/blackfin/mach-bf533/cpu.c
@@ -79,8 +79,7 @@ static int bf533_target(struct cpufreq_policy *policy,
79 int i; 79 int i;
80 80
81 struct cpufreq_freqs freqs; 81 struct cpufreq_freqs freqs;
82 if (cpufreq_frequency_table_target 82 if (cpufreq_frequency_table_target(policy, bf533_freq_table, target_freq, relation, &index))
83 (policy, bf533_freq_table, target_freq, relation, &index))
84 return -EINVAL; 83 return -EINVAL;
85 cclk_mhz = bf533_freq_table[index].frequency; 84 cclk_mhz = bf533_freq_table[index].frequency;
86 vco_mhz = bf533_freq_table[index].index; 85 vco_mhz = bf533_freq_table[index].index;
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
new file mode 100644
index 000000000000..6c909cf4f7bf
--- /dev/null
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -0,0 +1,95 @@
1/*
2 * File: arch/blackfin/mach-bf533/dma.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29#include <asm/blackfin.h>
30#include <asm/dma.h>
31
32struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
33 (struct dma_register *) DMA0_NEXT_DESC_PTR,
34 (struct dma_register *) DMA1_NEXT_DESC_PTR,
35 (struct dma_register *) DMA2_NEXT_DESC_PTR,
36 (struct dma_register *) DMA3_NEXT_DESC_PTR,
37 (struct dma_register *) DMA4_NEXT_DESC_PTR,
38 (struct dma_register *) DMA5_NEXT_DESC_PTR,
39 (struct dma_register *) DMA6_NEXT_DESC_PTR,
40 (struct dma_register *) DMA7_NEXT_DESC_PTR,
41 (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
42 (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
43 (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
44 (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
45};
46
47int channel2irq(unsigned int channel)
48{
49 int ret_irq = -1;
50
51 switch (channel) {
52 case CH_PPI:
53 ret_irq = IRQ_PPI;
54 break;
55
56 case CH_SPORT0_RX:
57 ret_irq = IRQ_SPORT0_RX;
58 break;
59
60 case CH_SPORT0_TX:
61 ret_irq = IRQ_SPORT0_TX;
62 break;
63
64 case CH_SPORT1_RX:
65 ret_irq = IRQ_SPORT1_RX;
66 break;
67
68 case CH_SPORT1_TX:
69 ret_irq = IRQ_SPORT1_TX;
70 break;
71
72 case CH_SPI:
73 ret_irq = IRQ_SPI;
74 break;
75
76 case CH_UART_RX:
77 ret_irq = IRQ_UART_RX;
78 break;
79
80 case CH_UART_TX:
81 ret_irq = IRQ_UART_TX;
82 break;
83
84 case CH_MEM_STREAM0_SRC:
85 case CH_MEM_STREAM0_DEST:
86 ret_irq = IRQ_MEM_DMA0;
87 break;
88
89 case CH_MEM_STREAM1_SRC:
90 case CH_MEM_STREAM1_DEST:
91 ret_irq = IRQ_MEM_DMA1;
92 break;
93 }
94 return ret_irq;
95}
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
index 7e2aa8d0f44f..7dd0e9c3a936 100644
--- a/arch/blackfin/mach-bf533/head.S
+++ b/arch/blackfin/mach-bf533/head.S
@@ -30,6 +30,7 @@
30#include <linux/linkage.h> 30#include <linux/linkage.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <asm/blackfin.h> 32#include <asm/blackfin.h>
33#include <asm/trace.h>
33#if CONFIG_BFIN_KERNEL_CLOCK 34#if CONFIG_BFIN_KERNEL_CLOCK
34#include <asm/mach/mem_init.h> 35#include <asm/mach/mem_init.h>
35#endif 36#endif
@@ -96,6 +97,10 @@ ENTRY(__start)
96 M2 = r0; 97 M2 = r0;
97 M3 = r0; 98 M3 = r0;
98 99
100 trace_buffer_start(p0,r0);
101 P0 = R1;
102 R0 = R1;
103
99#if CONFIG_DEBUG_KERNEL_START 104#if CONFIG_DEBUG_KERNEL_START
100 105
101/* 106/*
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
index a3e1789167be..7d79e0f9503d 100644
--- a/arch/blackfin/mach-bf533/ints-priority.c
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -28,8 +28,8 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/irq.h>
31#include <asm/blackfin.h> 32#include <asm/blackfin.h>
32#include <asm/irq.h>
33 33
34void program_IAR(void) 34void program_IAR(void)
35{ 35{
diff --git a/arch/blackfin/mach-bf537/Makefile b/arch/blackfin/mach-bf537/Makefile
index f32d44215bb7..7e7c9c8ac5b2 100644
--- a/arch/blackfin/mach-bf537/Makefile
+++ b/arch/blackfin/mach-bf537/Makefile
@@ -4,6 +4,6 @@
4 4
5extra-y := head.o 5extra-y := head.o
6 6
7obj-y := ints-priority.o 7obj-y := ints-priority.o dma.o
8 8
9obj-$(CONFIG_CPU_FREQ) += cpu.o 9obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index 6a60618a78ec..a8f947b72754 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -35,7 +35,7 @@
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 36#include <linux/spi/flash.h>
37#include <linux/usb_isp1362.h> 37#include <linux/usb_isp1362.h>
38#include <asm/irq.h> 38#include <linux/irq.h>
39#include <asm/bfin5xx_spi.h> 39#include <asm/bfin5xx_spi.h>
40 40
41/* 41/*
@@ -53,11 +53,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
53 .size = 0x00020000, 53 .size = 0x00020000,
54 .offset = 0, 54 .offset = 0,
55 .mask_flags = MTD_CAP_ROM 55 .mask_flags = MTD_CAP_ROM
56 },{ 56 }, {
57 .name = "kernel", 57 .name = "kernel",
58 .size = 0xe0000, 58 .size = 0xe0000,
59 .offset = 0x20000 59 .offset = 0x20000
60 },{ 60 }, {
61 .name = "file system", 61 .name = "file system",
62 .size = 0x700000, 62 .size = 0x700000,
63 .offset = 0x00100000, 63 .offset = 0x00100000,
@@ -202,7 +202,7 @@ static struct resource smc91x_resources[] = {
202 .start = 0x20200300, 202 .start = 0x20200300,
203 .end = 0x20200300 + 16, 203 .end = 0x20200300 + 16,
204 .flags = IORESOURCE_MEM, 204 .flags = IORESOURCE_MEM,
205 },{ 205 }, {
206 .start = IRQ_PF14, 206 .start = IRQ_PF14,
207 .end = IRQ_PF14, 207 .end = IRQ_PF14,
208 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 208 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -223,11 +223,11 @@ static struct resource isp1362_hcd_resources[] = {
223 .start = 0x20308000, 223 .start = 0x20308000,
224 .end = 0x20308000, 224 .end = 0x20308000,
225 .flags = IORESOURCE_MEM, 225 .flags = IORESOURCE_MEM,
226 },{ 226 }, {
227 .start = 0x20308004, 227 .start = 0x20308004,
228 .end = 0x20308004, 228 .end = 0x20308004,
229 .flags = IORESOURCE_MEM, 229 .flags = IORESOURCE_MEM,
230 },{ 230 }, {
231 .start = IRQ_PG15, 231 .start = IRQ_PG15,
232 .end = IRQ_PG15, 232 .end = IRQ_PG15,
233 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 233 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -262,7 +262,7 @@ static struct resource net2272_bfin_resources[] = {
262 .start = 0x20200000, 262 .start = 0x20200000,
263 .end = 0x20200000 + 0x100, 263 .end = 0x20200000 + 0x100,
264 .flags = IORESOURCE_MEM, 264 .flags = IORESOURCE_MEM,
265 },{ 265 }, {
266 .start = IRQ_PF7, 266 .start = IRQ_PF7,
267 .end = IRQ_PF7, 267 .end = IRQ_PF7,
268 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 268 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -283,7 +283,7 @@ static struct resource bfin_uart_resources[] = {
283 .start = 0xFFC00400, 283 .start = 0xFFC00400,
284 .end = 0xFFC004FF, 284 .end = 0xFFC004FF,
285 .flags = IORESOURCE_MEM, 285 .flags = IORESOURCE_MEM,
286 },{ 286 }, {
287 .start = 0xFFC02000, 287 .start = 0xFFC02000,
288 .end = 0xFFC020FF, 288 .end = 0xFFC020FF,
289 .flags = IORESOURCE_MEM, 289 .flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/eth_mac.c b/arch/blackfin/mach-bf537/boards/eth_mac.c
index e129a08d63de..a725cc8a9290 100644
--- a/arch/blackfin/mach-bf537/boards/eth_mac.c
+++ b/arch/blackfin/mach-bf537/boards/eth_mac.c
@@ -20,8 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <asm/blackfin.h> 21#include <asm/blackfin.h>
22 22
23#if defined(CONFIG_GENERIC_BOARD) \ 23#if defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
24 || defined(CONFIG_BFIN537_STAMP)
25 24
26/* 25/*
27 * Currently the MAC address is saved in Flash by U-Boot 26 * Currently the MAC address is saved in Flash by U-Boot
@@ -43,7 +42,7 @@ void get_bf537_ether_addr(char *addr)
43 */ 42 */
44void get_bf537_ether_addr(char *addr) 43void get_bf537_ether_addr(char *addr)
45{ 44{
46 printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__); 45 printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
47} 46}
48 47
49#endif 48#endif
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index fd57e7439e0f..648d984e98d6 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -35,9 +35,9 @@
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <linux/spi/flash.h> 36#include <linux/spi/flash.h>
37#include <linux/usb_isp1362.h> 37#include <linux/usb_isp1362.h>
38#include <asm/irq.h> 38#include <linux/irq.h>
39#include <asm/bfin5xx_spi.h>
40#include <linux/usb_sl811.h> 39#include <linux/usb_sl811.h>
40#include <asm/bfin5xx_spi.h>
41 41
42/* 42/*
43 * Name the Board for the /proc/cpuinfo 43 * Name the Board for the /proc/cpuinfo
@@ -54,19 +54,19 @@ static struct resource bfin_pcmcia_cf_resources[] = {
54 .start = 0x20310000, /* IO PORT */ 54 .start = 0x20310000, /* IO PORT */
55 .end = 0x20312000, 55 .end = 0x20312000,
56 .flags = IORESOURCE_MEM, 56 .flags = IORESOURCE_MEM,
57 },{ 57 }, {
58 .start = 0x20311000, /* Attribute Memory */ 58 .start = 0x20311000, /* Attribute Memory */
59 .end = 0x20311FFF, 59 .end = 0x20311FFF,
60 .flags = IORESOURCE_MEM, 60 .flags = IORESOURCE_MEM,
61 },{ 61 }, {
62 .start = IRQ_PROG_INTA, 62 .start = IRQ_PROG_INTA,
63 .end = IRQ_PROG_INTA, 63 .end = IRQ_PROG_INTA,
64 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 64 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
65 },{ 65 }, {
66 .start = IRQ_PF4, 66 .start = IRQ_PF4,
67 .end = IRQ_PF4, 67 .end = IRQ_PF4,
68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
69 },{ 69 }, {
70 .start = 6, /* Card Detect PF6 */ 70 .start = 6, /* Card Detect PF6 */
71 .end = 6, 71 .end = 6,
72 .flags = IORESOURCE_IRQ, 72 .flags = IORESOURCE_IRQ,
@@ -95,11 +95,11 @@ static struct resource smc91x_resources[] = {
95 .start = 0x20300300, 95 .start = 0x20300300,
96 .end = 0x20300300 + 16, 96 .end = 0x20300300 + 16,
97 .flags = IORESOURCE_MEM, 97 .flags = IORESOURCE_MEM,
98 },{ 98 }, {
99 .start = IRQ_PROG_INTB, 99 .start = IRQ_PROG_INTB,
100 .end = IRQ_PROG_INTB, 100 .end = IRQ_PROG_INTB,
101 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 101 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
102 },{ 102 }, {
103 /* 103 /*
104 * denotes the flag pin and is used directly if 104 * denotes the flag pin and is used directly if
105 * CONFIG_IRQCHIP_DEMUX_GPIO is defined. 105 * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
@@ -123,15 +123,15 @@ static struct resource sl811_hcd_resources[] = {
123 .start = 0x20340000, 123 .start = 0x20340000,
124 .end = 0x20340000, 124 .end = 0x20340000,
125 .flags = IORESOURCE_MEM, 125 .flags = IORESOURCE_MEM,
126 },{ 126 }, {
127 .start = 0x20340004, 127 .start = 0x20340004,
128 .end = 0x20340004, 128 .end = 0x20340004,
129 .flags = IORESOURCE_MEM, 129 .flags = IORESOURCE_MEM,
130 },{ 130 }, {
131 .start = IRQ_PROG_INTA, 131 .start = IRQ_PROG_INTA,
132 .end = IRQ_PROG_INTA, 132 .end = IRQ_PROG_INTA,
133 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 133 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
134 },{ 134 }, {
135 .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, 135 .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
136 .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, 136 .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
137 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 137 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -179,15 +179,15 @@ static struct resource isp1362_hcd_resources[] = {
179 .start = 0x20360000, 179 .start = 0x20360000,
180 .end = 0x20360000, 180 .end = 0x20360000,
181 .flags = IORESOURCE_MEM, 181 .flags = IORESOURCE_MEM,
182 },{ 182 }, {
183 .start = 0x20360004, 183 .start = 0x20360004,
184 .end = 0x20360004, 184 .end = 0x20360004,
185 .flags = IORESOURCE_MEM, 185 .flags = IORESOURCE_MEM,
186 },{ 186 }, {
187 .start = IRQ_PROG_INTA, 187 .start = IRQ_PROG_INTA,
188 .end = IRQ_PROG_INTA, 188 .end = IRQ_PROG_INTA,
189 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 189 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
190 },{ 190 }, {
191 .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO, 191 .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
192 .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO, 192 .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
193 .flags = IORESOURCE_IRQ, 193 .flags = IORESOURCE_IRQ,
@@ -228,7 +228,7 @@ static struct resource net2272_bfin_resources[] = {
228 .start = 0x20300000, 228 .start = 0x20300000,
229 .end = 0x20300000 + 0x100, 229 .end = 0x20300000 + 0x100,
230 .flags = IORESOURCE_MEM, 230 .flags = IORESOURCE_MEM,
231 },{ 231 }, {
232 .start = IRQ_PF7, 232 .start = IRQ_PF7,
233 .end = IRQ_PF7, 233 .end = IRQ_PF7,
234 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 234 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -253,11 +253,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
253 .size = 0x00020000, 253 .size = 0x00020000,
254 .offset = 0, 254 .offset = 0,
255 .mask_flags = MTD_CAP_ROM 255 .mask_flags = MTD_CAP_ROM
256 },{ 256 }, {
257 .name = "kernel", 257 .name = "kernel",
258 .size = 0xe0000, 258 .size = 0xe0000,
259 .offset = 0x20000 259 .offset = 0x20000
260 },{ 260 }, {
261 .name = "file system", 261 .name = "file system",
262 .size = 0x700000, 262 .size = 0x700000,
263 .offset = 0x00100000, 263 .offset = 0x00100000,
@@ -375,7 +375,7 @@ static struct resource bfin_uart_resources[] = {
375 .start = 0xFFC00400, 375 .start = 0xFFC00400,
376 .end = 0xFFC004FF, 376 .end = 0xFFC004FF,
377 .flags = IORESOURCE_MEM, 377 .flags = IORESOURCE_MEM,
378 },{ 378 }, {
379 .start = 0xFFC02000, 379 .start = 0xFFC02000,
380 .end = 0xFFC020FF, 380 .end = 0xFFC020FF,
381 .flags = IORESOURCE_MEM, 381 .flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 8aaf76dfce80..8806f1230f2d 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -37,7 +37,7 @@
37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
38#include <linux/usb_isp1362.h> 38#include <linux/usb_isp1362.h>
39#endif 39#endif
40#include <asm/irq.h> 40#include <linux/irq.h>
41#include <asm/bfin5xx_spi.h> 41#include <asm/bfin5xx_spi.h>
42#include <linux/usb_sl811.h> 42#include <linux/usb_sl811.h>
43 43
@@ -58,15 +58,15 @@ static struct resource bfin_pcmcia_cf_resources[] = {
58 .start = 0x20310000, /* IO PORT */ 58 .start = 0x20310000, /* IO PORT */
59 .end = 0x20312000, 59 .end = 0x20312000,
60 .flags = IORESOURCE_MEM, 60 .flags = IORESOURCE_MEM,
61 },{ 61 }, {
62 .start = 0x20311000, /* Attribute Memory */ 62 .start = 0x20311000, /* Attribute Memory */
63 .end = 0x20311FFF, 63 .end = 0x20311FFF,
64 .flags = IORESOURCE_MEM, 64 .flags = IORESOURCE_MEM,
65 },{ 65 }, {
66 .start = IRQ_PF4, 66 .start = IRQ_PF4,
67 .end = IRQ_PF4, 67 .end = IRQ_PF4,
68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 68 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
69 },{ 69 }, {
70 .start = 6, /* Card Detect PF6 */ 70 .start = 6, /* Card Detect PF6 */
71 .end = 6, 71 .end = 6,
72 .flags = IORESOURCE_IRQ, 72 .flags = IORESOURCE_IRQ,
@@ -95,7 +95,7 @@ static struct resource smc91x_resources[] = {
95 .start = 0x20300300, 95 .start = 0x20300300,
96 .end = 0x20300300 + 16, 96 .end = 0x20300300 + 16,
97 .flags = IORESOURCE_MEM, 97 .flags = IORESOURCE_MEM,
98 },{ 98 }, {
99 99
100 .start = IRQ_PF7, 100 .start = IRQ_PF7,
101 .end = IRQ_PF7, 101 .end = IRQ_PF7,
@@ -116,11 +116,11 @@ static struct resource sl811_hcd_resources[] = {
116 .start = 0x20340000, 116 .start = 0x20340000,
117 .end = 0x20340000, 117 .end = 0x20340000,
118 .flags = IORESOURCE_MEM, 118 .flags = IORESOURCE_MEM,
119 },{ 119 }, {
120 .start = 0x20340004, 120 .start = 0x20340004,
121 .end = 0x20340004, 121 .end = 0x20340004,
122 .flags = IORESOURCE_MEM, 122 .flags = IORESOURCE_MEM,
123 },{ 123 }, {
124 .start = CONFIG_USB_SL811_BFIN_IRQ, 124 .start = CONFIG_USB_SL811_BFIN_IRQ,
125 .end = CONFIG_USB_SL811_BFIN_IRQ, 125 .end = CONFIG_USB_SL811_BFIN_IRQ,
126 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 126 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -167,11 +167,11 @@ static struct resource isp1362_hcd_resources[] = {
167 .start = 0x20360000, 167 .start = 0x20360000,
168 .end = 0x20360000, 168 .end = 0x20360000,
169 .flags = IORESOURCE_MEM, 169 .flags = IORESOURCE_MEM,
170 },{ 170 }, {
171 .start = 0x20360004, 171 .start = 0x20360004,
172 .end = 0x20360004, 172 .end = 0x20360004,
173 .flags = IORESOURCE_MEM, 173 .flags = IORESOURCE_MEM,
174 },{ 174 }, {
175 .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, 175 .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
176 .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, 176 .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
177 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 177 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -212,7 +212,7 @@ static struct resource net2272_bfin_resources[] = {
212 .start = 0x20300000, 212 .start = 0x20300000,
213 .end = 0x20300000 + 0x100, 213 .end = 0x20300000 + 0x100,
214 .flags = IORESOURCE_MEM, 214 .flags = IORESOURCE_MEM,
215 },{ 215 }, {
216 .start = IRQ_PF7, 216 .start = IRQ_PF7,
217 .end = IRQ_PF7, 217 .end = IRQ_PF7,
218 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 218 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -238,11 +238,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
238 .size = 0x00020000, 238 .size = 0x00020000,
239 .offset = 0, 239 .offset = 0,
240 .mask_flags = MTD_CAP_ROM 240 .mask_flags = MTD_CAP_ROM
241 },{ 241 }, {
242 .name = "kernel", 242 .name = "kernel",
243 .size = 0xe0000, 243 .size = 0xe0000,
244 .offset = 0x20000 244 .offset = 0x20000
245 },{ 245 }, {
246 .name = "file system", 246 .name = "file system",
247 .size = 0x700000, 247 .size = 0x700000,
248 .offset = 0x00100000, 248 .offset = 0x00100000,
@@ -294,16 +294,6 @@ static struct bfin5xx_spi_chip spi_mmc_chip_info = {
294}; 294};
295#endif 295#endif
296 296
297#if defined(CONFIG_PBX)
298static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
299 .ctl_reg = 0x4, /* send zero */
300 .enable_dma = 0,
301 .bits_per_word = 8,
302 .cs_change_per_word = 1,
303};
304#endif
305
306
307#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 297#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
308static struct bfin5xx_spi_chip spi_ad7877_chip_info = { 298static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
309 .cs_change_per_word = 1, 299 .cs_change_per_word = 1,
@@ -392,24 +382,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
392 .mode = SPI_MODE_3, 382 .mode = SPI_MODE_3,
393 }, 383 },
394#endif 384#endif
395#if defined(CONFIG_PBX)
396 {
397 .modalias = "fxs-spi",
398 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
399 .bus_num = 1,
400 .chip_select = 3,
401 .controller_data= &spi_si3xxx_chip_info,
402 .mode = SPI_MODE_3,
403 },
404 {
405 .modalias = "fxo-spi",
406 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
407 .bus_num = 1,
408 .chip_select = 2,
409 .controller_data= &spi_si3xxx_chip_info,
410 .mode = SPI_MODE_3,
411 },
412#endif
413#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 385#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
414{ 386{
415 .modalias = "ad7877", 387 .modalias = "ad7877",
@@ -451,7 +423,7 @@ static struct resource bfin_uart_resources[] = {
451 .start = 0xFFC00400, 423 .start = 0xFFC00400,
452 .end = 0xFFC004FF, 424 .end = 0xFFC004FF,
453 .flags = IORESOURCE_MEM, 425 .flags = IORESOURCE_MEM,
454 },{ 426 }, {
455 .start = 0xFFC02000, 427 .start = 0xFFC02000,
456 .end = 0xFFC020FF, 428 .end = 0xFFC020FF,
457 .flags = IORESOURCE_MEM, 429 .flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 3a29b4d15f25..9c43d7756510 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -37,12 +37,10 @@
37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 37#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
38#include <linux/usb_isp1362.h> 38#include <linux/usb_isp1362.h>
39#endif 39#endif
40#include <asm/irq.h>
41#include <linux/irq.h> 40#include <linux/irq.h>
42#include <linux/interrupt.h> 41#include <linux/interrupt.h>
43#include <asm/bfin5xx_spi.h>
44#include <linux/usb_sl811.h> 42#include <linux/usb_sl811.h>
45 43#include <asm/bfin5xx_spi.h>
46#include <linux/spi/ad7877.h> 44#include <linux/spi/ad7877.h>
47 45
48/* 46/*
@@ -85,7 +83,7 @@ static struct platform_device *bfin_isp1761_devices[] = {
85 83
86int __init bfin_isp1761_init(void) 84int __init bfin_isp1761_init(void)
87{ 85{
88 unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices); 86 unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
89 87
90 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); 88 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
91 set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); 89 set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -107,15 +105,15 @@ static struct resource bfin_pcmcia_cf_resources[] = {
107 .start = 0x20310000, /* IO PORT */ 105 .start = 0x20310000, /* IO PORT */
108 .end = 0x20312000, 106 .end = 0x20312000,
109 .flags = IORESOURCE_MEM, 107 .flags = IORESOURCE_MEM,
110 },{ 108 }, {
111 .start = 0x20311000, /* Attribute Memory */ 109 .start = 0x20311000, /* Attribute Memory */
112 .end = 0x20311FFF, 110 .end = 0x20311FFF,
113 .flags = IORESOURCE_MEM, 111 .flags = IORESOURCE_MEM,
114 },{ 112 }, {
115 .start = IRQ_PF4, 113 .start = IRQ_PF4,
116 .end = IRQ_PF4, 114 .end = IRQ_PF4,
117 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 115 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
118 },{ 116 }, {
119 .start = 6, /* Card Detect PF6 */ 117 .start = 6, /* Card Detect PF6 */
120 .end = 6, 118 .end = 6,
121 .flags = IORESOURCE_IRQ, 119 .flags = IORESOURCE_IRQ,
@@ -144,7 +142,7 @@ static struct resource smc91x_resources[] = {
144 .start = 0x20300300, 142 .start = 0x20300300,
145 .end = 0x20300300 + 16, 143 .end = 0x20300300 + 16,
146 .flags = IORESOURCE_MEM, 144 .flags = IORESOURCE_MEM,
147 },{ 145 }, {
148 146
149 .start = IRQ_PF7, 147 .start = IRQ_PF7,
150 .end = IRQ_PF7, 148 .end = IRQ_PF7,
@@ -159,17 +157,39 @@ static struct platform_device smc91x_device = {
159}; 157};
160#endif 158#endif
161 159
160#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
161static struct resource dm9000_resources[] = {
162 [0] = {
163 .start = 0x203FB800,
164 .end = 0x203FB800 + 8,
165 .flags = IORESOURCE_MEM,
166 },
167 [1] = {
168 .start = IRQ_PF9,
169 .end = IRQ_PF9,
170 .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
171 },
172};
173
174static struct platform_device dm9000_device = {
175 .name = "dm9000",
176 .id = -1,
177 .num_resources = ARRAY_SIZE(dm9000_resources),
178 .resource = dm9000_resources,
179};
180#endif
181
162#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) 182#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
163static struct resource sl811_hcd_resources[] = { 183static struct resource sl811_hcd_resources[] = {
164 { 184 {
165 .start = 0x20340000, 185 .start = 0x20340000,
166 .end = 0x20340000, 186 .end = 0x20340000,
167 .flags = IORESOURCE_MEM, 187 .flags = IORESOURCE_MEM,
168 },{ 188 }, {
169 .start = 0x20340004, 189 .start = 0x20340004,
170 .end = 0x20340004, 190 .end = 0x20340004,
171 .flags = IORESOURCE_MEM, 191 .flags = IORESOURCE_MEM,
172 },{ 192 }, {
173 .start = CONFIG_USB_SL811_BFIN_IRQ, 193 .start = CONFIG_USB_SL811_BFIN_IRQ,
174 .end = CONFIG_USB_SL811_BFIN_IRQ, 194 .end = CONFIG_USB_SL811_BFIN_IRQ,
175 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 195 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -216,11 +236,11 @@ static struct resource isp1362_hcd_resources[] = {
216 .start = 0x20360000, 236 .start = 0x20360000,
217 .end = 0x20360000, 237 .end = 0x20360000,
218 .flags = IORESOURCE_MEM, 238 .flags = IORESOURCE_MEM,
219 },{ 239 }, {
220 .start = 0x20360004, 240 .start = 0x20360004,
221 .end = 0x20360004, 241 .end = 0x20360004,
222 .flags = IORESOURCE_MEM, 242 .flags = IORESOURCE_MEM,
223 },{ 243 }, {
224 .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, 244 .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
225 .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, 245 .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
226 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 246 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -261,7 +281,7 @@ static struct resource net2272_bfin_resources[] = {
261 .start = 0x20300000, 281 .start = 0x20300000,
262 .end = 0x20300000 + 0x100, 282 .end = 0x20300000 + 0x100,
263 .flags = IORESOURCE_MEM, 283 .flags = IORESOURCE_MEM,
264 },{ 284 }, {
265 .start = IRQ_PF7, 285 .start = IRQ_PF7,
266 .end = IRQ_PF7, 286 .end = IRQ_PF7,
267 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 287 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -287,11 +307,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
287 .size = 0x00020000, 307 .size = 0x00020000,
288 .offset = 0, 308 .offset = 0,
289 .mask_flags = MTD_CAP_ROM 309 .mask_flags = MTD_CAP_ROM
290 },{ 310 }, {
291 .name = "kernel", 311 .name = "kernel",
292 .size = 0xe0000, 312 .size = 0xe0000,
293 .offset = 0x20000 313 .offset = 0x20000
294 },{ 314 }, {
295 .name = "file system", 315 .name = "file system",
296 .size = 0x700000, 316 .size = 0x700000,
297 .offset = 0x00100000, 317 .offset = 0x00100000,
@@ -361,7 +381,6 @@ static struct bfin5xx_spi_chip ad5304_chip_info = {
361 381
362#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 382#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
363static struct bfin5xx_spi_chip spi_ad7877_chip_info = { 383static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
364// .cs_change_per_word = 1,
365 .enable_dma = 0, 384 .enable_dma = 0,
366 .bits_per_word = 16, 385 .bits_per_word = 16,
367}; 386};
@@ -449,19 +468,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
449#endif 468#endif
450#if defined(CONFIG_PBX) 469#if defined(CONFIG_PBX)
451 { 470 {
452 .modalias = "fxs-spi", 471 .modalias = "fxs-spi",
453 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ 472 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
454 .bus_num = 1, 473 .bus_num = 1,
455 .chip_select = 3, 474 .chip_select = 3,
456 .controller_data= &spi_si3xxx_chip_info, 475 .controller_data = &spi_si3xxx_chip_info,
457 .mode = SPI_MODE_3, 476 .mode = SPI_MODE_3,
458 }, 477 },
459 { 478 {
460 .modalias = "fxo-spi", 479 .modalias = "fxo-spi",
461 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ 480 .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
462 .bus_num = 1, 481 .bus_num = 1,
463 .chip_select = 2, 482 .chip_select = 2,
464 .controller_data= &spi_si3xxx_chip_info, 483 .controller_data = &spi_si3xxx_chip_info,
465 .mode = SPI_MODE_3, 484 .mode = SPI_MODE_3,
466 }, 485 },
467#endif 486#endif
@@ -516,7 +535,7 @@ static struct resource bfin_uart_resources[] = {
516 .start = 0xFFC00400, 535 .start = 0xFFC00400,
517 .end = 0xFFC004FF, 536 .end = 0xFFC004FF,
518 .flags = IORESOURCE_MEM, 537 .flags = IORESOURCE_MEM,
519 },{ 538 }, {
520 .start = 0xFFC02000, 539 .start = 0xFFC02000,
521 .end = 0xFFC020FF, 540 .end = 0xFFC020FF,
522 .flags = IORESOURCE_MEM, 541 .flags = IORESOURCE_MEM,
@@ -571,6 +590,10 @@ static struct platform_device *stamp_devices[] __initdata = {
571 &smc91x_device, 590 &smc91x_device,
572#endif 591#endif
573 592
593#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
594 &dm9000_device,
595#endif
596
574#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) 597#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
575 &bfin_mac_device, 598 &bfin_mac_device,
576#endif 599#endif
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
new file mode 100644
index 000000000000..706cb97b0265
--- /dev/null
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -0,0 +1,115 @@
1/*
2 * File: arch/blackfin/mach-bf537/dma.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29#include <asm/blackfin.h>
30#include <asm/dma.h>
31
32struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
33 (struct dma_register *) DMA0_NEXT_DESC_PTR,
34 (struct dma_register *) DMA1_NEXT_DESC_PTR,
35 (struct dma_register *) DMA2_NEXT_DESC_PTR,
36 (struct dma_register *) DMA3_NEXT_DESC_PTR,
37 (struct dma_register *) DMA4_NEXT_DESC_PTR,
38 (struct dma_register *) DMA5_NEXT_DESC_PTR,
39 (struct dma_register *) DMA6_NEXT_DESC_PTR,
40 (struct dma_register *) DMA7_NEXT_DESC_PTR,
41 (struct dma_register *) DMA8_NEXT_DESC_PTR,
42 (struct dma_register *) DMA9_NEXT_DESC_PTR,
43 (struct dma_register *) DMA10_NEXT_DESC_PTR,
44 (struct dma_register *) DMA11_NEXT_DESC_PTR,
45 (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
46 (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
47 (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
48 (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
49};
50
51int channel2irq(unsigned int channel)
52{
53 int ret_irq = -1;
54
55 switch (channel) {
56 case CH_PPI:
57 ret_irq = IRQ_PPI;
58 break;
59
60 case CH_EMAC_RX:
61 ret_irq = IRQ_MAC_RX;
62 break;
63
64 case CH_EMAC_TX:
65 ret_irq = IRQ_MAC_TX;
66 break;
67
68 case CH_UART1_RX:
69 ret_irq = IRQ_UART1_RX;
70 break;
71
72 case CH_UART1_TX:
73 ret_irq = IRQ_UART1_TX;
74 break;
75
76 case CH_SPORT0_RX:
77 ret_irq = IRQ_SPORT0_RX;
78 break;
79
80 case CH_SPORT0_TX:
81 ret_irq = IRQ_SPORT0_TX;
82 break;
83
84 case CH_SPORT1_RX:
85 ret_irq = IRQ_SPORT1_RX;
86 break;
87
88 case CH_SPORT1_TX:
89 ret_irq = IRQ_SPORT1_TX;
90 break;
91
92 case CH_SPI:
93 ret_irq = IRQ_SPI;
94 break;
95
96 case CH_UART_RX:
97 ret_irq = IRQ_UART_RX;
98 break;
99
100 case CH_UART_TX:
101 ret_irq = IRQ_UART_TX;
102 break;
103
104 case CH_MEM_STREAM0_SRC:
105 case CH_MEM_STREAM0_DEST:
106 ret_irq = IRQ_MEM_DMA0;
107 break;
108
109 case CH_MEM_STREAM1_SRC:
110 case CH_MEM_STREAM1_DEST:
111 ret_irq = IRQ_MEM_DMA1;
112 break;
113 }
114 return ret_irq;
115}
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
index 7d902bbd860f..429c8a1019da 100644
--- a/arch/blackfin/mach-bf537/head.S
+++ b/arch/blackfin/mach-bf537/head.S
@@ -30,6 +30,8 @@
30#include <linux/linkage.h> 30#include <linux/linkage.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <asm/blackfin.h> 32#include <asm/blackfin.h>
33#include <asm/trace.h>
34
33#if CONFIG_BFIN_KERNEL_CLOCK 35#if CONFIG_BFIN_KERNEL_CLOCK
34#include <asm/mach/mem_init.h> 36#include <asm/mach/mem_init.h>
35#endif 37#endif
@@ -93,6 +95,10 @@ ENTRY(__start)
93 M2 = r0; 95 M2 = r0;
94 M3 = r0; 96 M3 = r0;
95 97
98 trace_buffer_start(p0,r0);
99 P0 = R1;
100 R0 = R1;
101
96 /* Turn off the icache */ 102 /* Turn off the icache */
97 p0.l = (IMEM_CONTROL & 0xFFFF); 103 p0.l = (IMEM_CONTROL & 0xFFFF);
98 p0.h = (IMEM_CONTROL >> 16); 104 p0.h = (IMEM_CONTROL >> 16);
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
index 2dbf3df465d1..a8b915f202ec 100644
--- a/arch/blackfin/mach-bf537/ints-priority.c
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -28,8 +28,8 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/irq.h>
31#include <asm/blackfin.h> 32#include <asm/blackfin.h>
32#include <asm/irq.h>
33 33
34void program_IAR(void) 34void program_IAR(void)
35{ 35{
diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig
new file mode 100644
index 000000000000..e78b03d56c7c
--- /dev/null
+++ b/arch/blackfin/mach-bf548/Kconfig
@@ -0,0 +1,316 @@
1if (BF54x)
2
3menu "BF548 Specific Configuration"
4
5comment "Interrupt Priority Assignment"
6menu "Priority"
7
8config IRQ_PLL_WAKEUP
9 int "IRQ_PLL_WAKEUP"
10 default 7
11config IRQ_DMAC0_ERR
12 int "IRQ_DMAC0_ERR"
13 default 7
14config IRQ_EPPI0_ERR
15 int "IRQ_EPPI0_ERR"
16 default 7
17config IRQ_SPORT0_ERR
18 int "IRQ_SPORT0_ERR"
19 default 7
20config IRQ_SPORT1_ERR
21 int "IRQ_SPORT1_ERR"
22 default 7
23config IRQ_SPI0_ERR
24 int "IRQ_SPI0_ERR"
25 default 7
26config IRQ_UART0_ERR
27 int "IRQ_UART0_ERR"
28 default 7
29config IRQ_RTC
30 int "IRQ_RTC"
31 default 8
32config IRQ_EPPI0
33 int "IRQ_EPPI0"
34 default 8
35config IRQ_SPORT0_RX
36 int "IRQ_SPORT0_RX"
37 default 9
38config IRQ_SPORT0_TX
39 int "IRQ_SPORT0_TX"
40 default 9
41config IRQ_SPORT1_RX
42 int "IRQ_SPORT1_RX"
43 default 9
44config IRQ_SPORT1_TX
45 int "IRQ_SPORT1_TX"
46 default 9
47config IRQ_SPI0
48 int "IRQ_SPI0"
49 default 10
50config IRQ_UART0_RX
51 int "IRQ_UART0_RX"
52 default 10
53config IRQ_UART0_TX
54 int "IRQ_UART0_TX"
55 default 10
56config IRQ_TIMER8
57 int "IRQ_TIMER8"
58 default 11
59config IRQ_TIMER9
60 int "IRQ_TIMER9"
61 default 11
62config IRQ_TIMER10
63 int "IRQ_TIMER10"
64 default 11
65config IRQ_PINT0
66 int "IRQ_PINT0"
67 default 12
68config IRQ_PINT1
69 int "IRQ_PINT0"
70 default 12
71config IRQ_MDMAS0
72 int "IRQ_MDMAS0"
73 default 13
74config IRQ_MDMAS1
75 int "IRQ_DMDMAS1"
76 default 13
77config IRQ_WATCHDOG
78 int "IRQ_WATCHDOG"
79 default 13
80config IRQ_DMAC1_ERR
81 int "IRQ_DMAC1_ERR"
82 default 7
83config IRQ_SPORT2_ERR
84 int "IRQ_SPORT2_ERR"
85 default 7
86config IRQ_SPORT3_ERR
87 int "IRQ_SPORT3_ERR"
88 default 7
89config IRQ_MXVR_DATA
90 int "IRQ MXVR Data"
91 default 7
92config IRQ_SPI1_ERR
93 int "IRQ_SPI1_ERR"
94 default 7
95config IRQ_SPI2_ERR
96 int "IRQ_SPI2_ERR"
97 default 7
98config IRQ_UART1_ERR
99 int "IRQ_UART1_ERR"
100 default 7
101config IRQ_UART2_ERR
102 int "IRQ_UART2_ERR"
103 default 7
104config IRQ_CAN0_ERR
105 int "IRQ_CAN0_ERR"
106 default 7
107config IRQ_SPORT2_RX
108 int "IRQ_SPORT2_RX"
109 default 9
110config IRQ_SPORT2_TX
111 int "IRQ_SPORT2_TX"
112 default 9
113config IRQ_SPORT3_RX
114 int "IRQ_SPORT3_RX"
115 default 9
116config IRQ_SPORT3_TX
117 int "IRQ_SPORT3_TX"
118 default 9
119config IRQ_EPPI1
120 int "IRQ_EPPI1"
121 default 9
122config IRQ_EPPI2
123 int "IRQ_EPPI2"
124 default 9
125config IRQ_SPI1
126 int "IRQ_SPI1"
127 default 10
128config IRQ_SPI2
129 int "IRQ_SPI2"
130 default 10
131config IRQ_UART1_RX
132 int "IRQ_UART1_RX"
133 default 10
134config IRQ_UART1_TX
135 int "IRQ_UART1_TX"
136 default 10
137config IRQ_ATAPI_RX
138 int "IRQ_ATAPI_RX"
139 default 10
140config IRQ_ATAPI_TX
141 int "IRQ_ATAPI_TX"
142 default 10
143config IRQ_TWI0
144 int "IRQ_TWI0"
145 default 11
146config IRQ_TWI1
147 int "IRQ_TWI1"
148 default 11
149config IRQ_CAN0_RX
150 int "IRQ_CAN_RX"
151 default 11
152config IRQ_CAN0_TX
153 int "IRQ_CAN_TX"
154 default 11
155config IRQ_MDMAS2
156 int "IRQ_MDMAS2"
157 default 13
158config IRQ_MDMAS3
159 int "IRQ_DMMAS3"
160 default 13
161config IRQ_MXVR_ERR
162 int "IRQ_MXVR_ERR"
163 default 11
164config IRQ_MXVR_MSG
165 int "IRQ_MXVR_MSG"
166 default 11
167config IRQ_MXVR_PKT
168 int "IRQ_MXVR_PKT"
169 default 11
170config IRQ_EPPI1_ERR
171 int "IRQ_EPPI1_ERR"
172 default 7
173config IRQ_EPPI2_ERR
174 int "IRQ_EPPI2_ERR"
175 default 7
176config IRQ_UART3_ERR
177 int "IRQ_UART3_ERR"
178 default 7
179config IRQ_HOST_ERR
180 int "IRQ_HOST_ERR"
181 default 7
182config IRQ_PIXC_ERR
183 int "IRQ_PIXC_ERR"
184 default 7
185config IRQ_NFC_ERR
186 int "IRQ_NFC_ERR"
187 default 7
188config IRQ_ATAPI_ERR
189 int "IRQ_ATAPI_ERR"
190 default 7
191config IRQ_CAN1_ERR
192 int "IRQ_CAN1_ERR"
193 default 7
194config IRQ_HS_DMA_ERR
195 int "IRQ Handshake DMA Status"
196 default 7
197config IRQ_PIXC_IN0
198 int "IRQ PIXC IN0"
199 default 8
200config IRQ_PIXC_IN1
201 int "IRQ PIXC IN1"
202 default 8
203config IRQ_PIXC_OUT
204 int "IRQ PIXC OUT"
205 default 8
206config IRQ_SDH
207 int "IRQ SDH"
208 default 8
209config IRQ_CNT
210 int "IRQ CNT"
211 default 8
212config IRQ_KEY
213 int "IRQ KEY"
214 default 8
215config IRQ_CAN1_RX
216 int "IRQ CAN1 RX"
217 default 11
218config IRQ_CAN1_TX
219 int "IRQ_CAN1_TX"
220 default 11
221config IRQ_SDH_MASK0
222 int "IRQ_SDH_MASK0"
223 default 11
224config IRQ_SDH_MASK1
225 int "IRQ_SDH_MASK1"
226 default 11
227config IRQ_USB_INT0
228 int "IRQ USB INT0"
229 default 11
230config IRQ_USB_INT1
231 int "IRQ USB INT1"
232 default 11
233config IRQ_USB_INT2
234 int "IRQ USB INT2"
235 default 11
236config IRQ_USB_DMA
237 int "IRQ USB DMA"
238 default 11
239config IRQ_OTPSEC
240 int "IRQ OPTSEC"
241 default 11
242config IRQ_TIMER0
243 int "IRQ_TIMER0"
244 default 11
245config IRQ_TIMER1
246 int "IRQ_TIMER1"
247 default 11
248config IRQ_TIMER2
249 int "IRQ_TIMER2"
250 default 11
251config IRQ_TIMER3
252 int "IRQ_TIMER3"
253 default 11
254config IRQ_TIMER4
255 int "IRQ_TIMER4"
256 default 11
257config IRQ_TIMER5
258 int "IRQ_TIMER5"
259 default 11
260config IRQ_TIMER6
261 int "IRQ_TIMER6"
262 default 11
263config IRQ_TIMER7
264 int "IRQ_TIMER7"
265 default 11
266config IRQ_PINT2
267 int "IRQ_PIN2"
268 default 11
269config IRQ_PINT3
270 int "IRQ_PIN3"
271 default 11
272
273 help
274 Enter the priority numbers between 7-13 ONLY. Others are Reserved.
275 This applies to all the above. It is not recommended to assign the
276 highest priority number 7 to UART or any other device.
277
278endmenu
279
280comment "Pin Interrupt to Port Assignment"
281menu "Assignment"
282
283config PINTx_REASSIGN
284 bool "Reprogram PINT Assignment"
285 default n
286 help
287 The interrupt assignment registers controls the pin-to-interrupt
288 assignment in a byte-wide manner. Each option allows you to select
289 a set of pins (High/Low Byte) of an specific Port being mapped
290 to one of the four PIN Interrupts IRQ_PINTx.
291
292 You shouldn't change any of these unless you know exactly what you're doing.
293 Please consult the Blackfin BF54x Processor Hardware Reference Manual.
294
295config PINT0_ASSIGN
296 hex "PINT0_ASSIGN"
297 depends on PINTx_REASSIGN
298 default 0x00000101
299config PINT1_ASSIGN
300 hex "PINT1_ASSIGN"
301 depends on PINTx_REASSIGN
302 default 0x01010000
303config PINT2_ASSIGN
304 hex "PINT2_ASSIGN"
305 depends on PINTx_REASSIGN
306 default 0x00000101
307config PINT3_ASSIGN
308 hex "PINT3_ASSIGN"
309 depends on PINTx_REASSIGN
310 default 0x02020303
311
312endmenu
313
314endmenu
315
316endif
diff --git a/arch/blackfin/mach-bf548/Makefile b/arch/blackfin/mach-bf548/Makefile
new file mode 100644
index 000000000000..060ad78ebf1d
--- /dev/null
+++ b/arch/blackfin/mach-bf548/Makefile
@@ -0,0 +1,9 @@
1#
2# arch/blackfin/mach-bf537/Makefile
3#
4
5extra-y := head.o
6
7obj-y := ints-priority.o dma.o gpio.o
8
9obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf548/boards/Makefile b/arch/blackfin/mach-bf548/boards/Makefile
new file mode 100644
index 000000000000..486e07c99a51
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/Makefile
@@ -0,0 +1,5 @@
1#
2# arch/blackfin/mach-bf548/boards/Makefile
3#
4
5obj-$(CONFIG_BFIN548_EZKIT) += ezkit.o led.o
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
new file mode 100644
index 000000000000..96ad95fab1a8
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -0,0 +1,114 @@
1/*
2 * File: arch/blackfin/mach-bf548/boards/ezkit.c
3 * Based on: arch/blackfin/mach-bf537/boards/ezkit.c
4 * Author: Aidan Williams <aidan@nicta.com.au>
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2007 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#include <linux/device.h>
32#include <linux/platform_device.h>
33#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h>
35#include <linux/spi/spi.h>
36#include <linux/spi/flash.h>
37#include <linux/irq.h>
38#include <linux/irq.h>
39#include <linux/interrupt.h>
40#include <asm/bfin5xx_spi.h>
41
42/*
43 * Name the Board for the /proc/cpuinfo
44 */
45char *bfin_board_name = "ADSP-BF548-EZKIT";
46
47/*
48 * Driver needs to know address, irq and flag pin.
49 */
50
51#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
52static struct platform_device rtc_device = {
53 .name = "rtc-bfin",
54 .id = -1,
55};
56#endif
57
58#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
59static struct resource bfin_uart_resources[] = {
60#ifdef CONFIG_SERIAL_BFIN_UART0
61 {
62 .start = 0xFFC00400,
63 .end = 0xFFC004FF,
64 .flags = IORESOURCE_MEM,
65 },
66#endif
67#ifdef CONFIG_SERIAL_BFIN_UART1
68 {
69 .start = 0xFFC02000,
70 .end = 0xFFC020FF,
71 .flags = IORESOURCE_MEM,
72 },
73#endif
74#ifdef CONFIG_SERIAL_BFIN_UART2
75 {
76 .start = 0xFFC02100,
77 .end = 0xFFC021FF,
78 .flags = IORESOURCE_MEM,
79 },
80#endif
81#ifdef CONFIG_SERIAL_BFIN_UART3
82 {
83 .start = 0xFFC03100,
84 .end = 0xFFC031FF,
85 },
86#endif
87};
88
89static struct platform_device bfin_uart_device = {
90 .name = "bfin-uart",
91 .id = 1,
92 .num_resources = ARRAY_SIZE(bfin_uart_resources),
93 .resource = bfin_uart_resources,
94};
95#endif
96
97static struct platform_device *ezkit_devices[] __initdata = {
98#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
99 &rtc_device,
100#endif
101
102#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
103 &bfin_uart_device,
104#endif
105};
106
107static int __init stamp_init(void)
108{
109 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
110 platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
111 return 0;
112}
113
114arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf548/boards/led.S b/arch/blackfin/mach-bf548/boards/led.S
new file mode 100644
index 000000000000..f47daf3770d0
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/led.S
@@ -0,0 +1,172 @@
1/****************************************************
2 * LED1 ---- PG6 LED2 ---- PG7 *
3 * LED3 ---- PG8 LED4 ---- PG9 *
4 * LED5 ---- PG10 LED6 ---- PG11 *
5 ****************************************************/
6
7#include <linux/linkage.h>
8#include <asm/blackfin.h>
9
10/* All functions in this file save the registers they uses.
11 So there is no need to save any registers before calling them. */
12
13 .text;
14
15/* Initialize LEDs. */
16
17ENTRY(_led_init)
18 LINK 0;
19 [--SP] = P0;
20 [--SP] = R0;
21 [--SP] = R1;
22 [--SP] = R2;
23 R1 = (PG6|PG7|PG8|PG9|PG10|PG11)(Z);
24 R2 = ~R1;
25
26 P0.H = hi(PORTG_FER);
27 P0.L = lo(PORTG_FER);
28 R0 = W[P0](Z);
29 SSYNC;
30 R0 = R0 & R2;
31 W[P0] = R0.L;
32 SSYNC;
33
34 P0.H = hi(PORTG_DIR_SET);
35 P0.L = lo(PORTG_DIR_SET);
36 W[P0] = R1.L;
37 SSYNC;
38
39 P0.H = hi(PORTG_INEN);
40 P0.L = lo(PORTG_INEN);
41 R0 = W[P0](Z);
42 SSYNC;
43 R0 = R0 & R2;
44 W[P0] = R0.L;
45 SSYNC;
46
47 R2 = [SP++];
48 R1 = [SP++];
49 R0 = [SP++];
50 P0 = [SP++];
51 RTS;
52 .size _led_init, .-_led_init
53
54/* Set one LED on. Leave other LEDs unchanged.
55 It expects the LED number passed through R0. */
56
57ENTRY(_led_on)
58 LINK 0;
59 [--SP] = P0;
60 [--SP] = R1;
61 CALL _led_init;
62 R1 = 1;
63 R0 += 5;
64 R1 <<= R0;
65 P0.H = hi(PORTG_SET);
66 P0.L = lo(PORTG_SET);
67 W[P0] = R1.L;
68 SSYNC;
69 R1 = [SP++];
70 P0 = [SP++];
71 UNLINK;
72 RTS;
73 .size _led_on, .-_led_on
74
75/* Set one LED off. Leave other LEDs unchanged. */
76
77ENTRY(_led_off)
78 LINK 0;
79 [--SP] = P0;
80 [--SP] = R1;
81 CALL _led_init;
82 R1 = 1;
83 R0 += 5;
84 R1 <<= R0;
85 P0.H = hi(PORTG_CLEAR);
86 P0.L = lo(PORTG_CLEAR);
87 W[P0] = R1.L;
88 SSYNC;
89 R1 = [SP++];
90 P0 = [SP++];
91 UNLINK;
92 RTS;
93 .size _led_off, .-_led_off
94
95/* Toggle one LED. Leave other LEDs unchanged. */
96
97ENTRY(_led_toggle)
98 LINK 0;
99 [--SP] = P0;
100 [--SP] = R1;
101 CALL _led_init;
102 R1 = 1;
103 R0 += 5;
104 R1 <<= R0;
105 P0.H = hi(PORTG);
106 P0.L = lo(PORTG);
107 R0 = W[P0](Z);
108 SSYNC;
109 R0 = R0 ^ R1;
110 W[P0] = R0.L;
111 SSYNC;
112 R1 = [SP++];
113 P0 = [SP++];
114 UNLINK;
115 RTS;
116 .size _led_toggle, .-_led_toggle
117
118/* Display the number using LEDs in binary format. */
119
120ENTRY(_led_disp_num)
121 LINK 0;
122 [--SP] = P0;
123 [--SP] = R1;
124 [--SP] = R2;
125 CALL _led_init;
126 R1 = 0x3f(X);
127 R0 = R0 & R1;
128 R2 = 6(X);
129 R0 <<= R2;
130 R1 <<= R2;
131 P0.H = hi(PORTG);
132 P0.L = lo(PORTG);
133 R2 = W[P0](Z);
134 SSYNC;
135 R1 = ~R1;
136 R2 = R2 & R1;
137 R2 = R2 | R0;
138 W[P0] = R2.L;
139 SSYNC;
140 R2 = [SP++];
141 R1 = [SP++];
142 P0 = [SP++];
143 UNLINK;
144 RTS;
145 .size _led_disp_num, .-_led_disp_num
146
147/* Toggle the number using LEDs in binary format. */
148
149ENTRY(_led_toggle_num)
150 LINK 0;
151 [--SP] = P0;
152 [--SP] = R1;
153 [--SP] = R2;
154 CALL _led_init;
155 R1 = 0x3f(X);
156 R0 = R0 & R1;
157 R1 = 6(X);
158 R0 <<= R1;
159 P0.H = hi(PORTG);
160 P0.L = lo(PORTG);
161 R1 = W[P0](Z);
162 SSYNC;
163 R1 = R1 ^ R0;
164 W[P0] = R1.L;
165 SSYNC;
166 R2 = [SP++];
167 R1 = [SP++];
168 P0 = [SP++];
169 UNLINK;
170 RTS;
171 .size _led_toggle_num, .-_led_toggle_num
172
diff --git a/arch/blackfin/mach-bf548/cpu.c b/arch/blackfin/mach-bf548/cpu.c
new file mode 100644
index 000000000000..4298a3ccfbfc
--- /dev/null
+++ b/arch/blackfin/mach-bf548/cpu.c
@@ -0,0 +1,159 @@
1/*
2 * File: arch/blackfin/mach-bf548/cpu.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: clock scaling for the bf54x
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/types.h>
32#include <linux/init.h>
33#include <linux/cpufreq.h>
34#include <asm/dpmc.h>
35#include <linux/fs.h>
36#include <asm/bfin-global.h>
37
38/* CONFIG_CLKIN_HZ=25000000 */
39#define VCO5 (CONFIG_CLKIN_HZ*45)
40#define VCO4 (CONFIG_CLKIN_HZ*36)
41#define VCO3 (CONFIG_CLKIN_HZ*27)
42#define VCO2 (CONFIG_CLKIN_HZ*18)
43#define VCO1 (CONFIG_CLKIN_HZ*9)
44#define VCO(x) VCO##x
45
46#define MFREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
47/* frequency */
48static struct cpufreq_frequency_table bf548_freq_table[] = {
49 MFREQ(1),
50 MFREQ(3),
51 {VCO4, VCO4 / 2}, {VCO4, VCO4},
52 MFREQ(5),
53 {0, CPUFREQ_TABLE_END},
54};
55
56/*
57 * dpmc_fops->ioctl()
58 * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
59 */
60static int bf548_getfreq(unsigned int cpu)
61{
62 unsigned long cclk_mhz;
63
64 /* The driver only support single cpu */
65 if (cpu == 0)
66 dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
67 else
68 cclk_mhz = -1;
69
70 return cclk_mhz;
71}
72
73static int bf548_target(struct cpufreq_policy *policy,
74 unsigned int target_freq, unsigned int relation)
75{
76 unsigned long cclk_mhz;
77 unsigned long vco_mhz;
78 unsigned long flags;
79 unsigned int index;
80 struct cpufreq_freqs freqs;
81
82 if (cpufreq_frequency_table_target(policy, bf548_freq_table, target_freq, relation, &index))
83 return -EINVAL;
84
85 cclk_mhz = bf548_freq_table[index].frequency;
86 vco_mhz = bf548_freq_table[index].index;
87
88 dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
89 freqs.old = bf548_getfreq(0);
90 freqs.new = cclk_mhz;
91 freqs.cpu = 0;
92
93 pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
94 cclk_mhz, vco_mhz, index, target_freq, freqs.old);
95
96 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
97 local_irq_save(flags);
98 dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
99 local_irq_restore(flags);
100 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
101
102 vco_mhz = get_vco();
103 cclk_mhz = get_cclk();
104 return 0;
105}
106
107/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
108 * this platform, anyway.
109 */
110static int bf548_verify_speed(struct cpufreq_policy *policy)
111{
112 return cpufreq_frequency_table_verify(policy, &bf548_freq_table);
113}
114
115static int __init __bf548_cpu_init(struct cpufreq_policy *policy)
116{
117 if (policy->cpu != 0)
118 return -EINVAL;
119
120 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
121
122 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
123 /*Now ,only support one cpu */
124 policy->cur = bf548_getfreq(0);
125 cpufreq_frequency_table_get_attr(bf548_freq_table, policy->cpu);
126 return cpufreq_frequency_table_cpuinfo(policy, bf548_freq_table);
127}
128
129static struct freq_attr *bf548_freq_attr[] = {
130 &cpufreq_freq_attr_scaling_available_freqs,
131 NULL,
132};
133
134static struct cpufreq_driver bf548_driver = {
135 .verify = bf548_verify_speed,
136 .target = bf548_target,
137 .get = bf548_getfreq,
138 .init = __bf548_cpu_init,
139 .name = "bf548",
140 .owner = THIS_MODULE,
141 .attr = bf548_freq_attr,
142};
143
144static int __init bf548_cpu_init(void)
145{
146 return cpufreq_register_driver(&bf548_driver);
147}
148
149static void __exit bf548_cpu_exit(void)
150{
151 cpufreq_unregister_driver(&bf548_driver);
152}
153
154MODULE_AUTHOR("Mickael Kang");
155MODULE_DESCRIPTION("cpufreq driver for BF548 CPU");
156MODULE_LICENSE("GPL");
157
158module_init(bf548_cpu_init);
159module_exit(bf548_cpu_exit);
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
new file mode 100644
index 000000000000..a8184113be48
--- /dev/null
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -0,0 +1,156 @@
1/*
2 * File: arch/blackfin/mach-bf561/dma.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <asm/blackfin.h>
31#include <asm/dma.h>
32
33 struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
34 (struct dma_register *) DMA0_NEXT_DESC_PTR,
35 (struct dma_register *) DMA1_NEXT_DESC_PTR,
36 (struct dma_register *) DMA2_NEXT_DESC_PTR,
37 (struct dma_register *) DMA3_NEXT_DESC_PTR,
38 (struct dma_register *) DMA4_NEXT_DESC_PTR,
39 (struct dma_register *) DMA5_NEXT_DESC_PTR,
40 (struct dma_register *) DMA6_NEXT_DESC_PTR,
41 (struct dma_register *) DMA7_NEXT_DESC_PTR,
42 (struct dma_register *) DMA8_NEXT_DESC_PTR,
43 (struct dma_register *) DMA9_NEXT_DESC_PTR,
44 (struct dma_register *) DMA10_NEXT_DESC_PTR,
45 (struct dma_register *) DMA11_NEXT_DESC_PTR,
46 (struct dma_register *) DMA12_NEXT_DESC_PTR,
47 (struct dma_register *) DMA13_NEXT_DESC_PTR,
48 (struct dma_register *) DMA14_NEXT_DESC_PTR,
49 (struct dma_register *) DMA15_NEXT_DESC_PTR,
50 (struct dma_register *) DMA16_NEXT_DESC_PTR,
51 (struct dma_register *) DMA17_NEXT_DESC_PTR,
52 (struct dma_register *) DMA18_NEXT_DESC_PTR,
53 (struct dma_register *) DMA19_NEXT_DESC_PTR,
54 (struct dma_register *) DMA20_NEXT_DESC_PTR,
55 (struct dma_register *) DMA21_NEXT_DESC_PTR,
56 (struct dma_register *) DMA22_NEXT_DESC_PTR,
57 (struct dma_register *) DMA23_NEXT_DESC_PTR,
58 (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
59 (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
60 (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
61 (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
62 (struct dma_register *) MDMA_D2_NEXT_DESC_PTR,
63 (struct dma_register *) MDMA_S2_NEXT_DESC_PTR,
64 (struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
65 (struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
66};
67
68int channel2irq(unsigned int channel)
69{
70 int ret_irq = -1;
71
72 switch (channel) {
73 case CH_SPORT0_RX:
74 ret_irq = IRQ_SPORT0_RX;
75 break;
76 case CH_SPORT0_TX:
77 ret_irq = IRQ_SPORT0_TX;
78 break;
79 case CH_SPORT1_RX:
80 ret_irq = IRQ_SPORT1_RX;
81 break;
82 case CH_SPORT1_TX:
83 ret_irq = IRQ_SPORT1_TX;
84 case CH_SPI0:
85 ret_irq = IRQ_SPI0;
86 break;
87 case CH_SPI1:
88 ret_irq = IRQ_SPI1;
89 break;
90 case CH_UART0_RX:
91 ret_irq = IRQ_UART_RX;
92 break;
93 case CH_UART0_TX:
94 ret_irq = IRQ_UART_TX;
95 break;
96 case CH_UART1_RX:
97 ret_irq = IRQ_UART_RX;
98 break;
99 case CH_UART1_TX:
100 ret_irq = IRQ_UART_TX;
101 break;
102 case CH_EPPI0:
103 ret_irq = IRQ_EPPI0;
104 break;
105 case CH_EPPI1:
106 ret_irq = IRQ_EPPI1;
107 break;
108 case CH_EPPI2:
109 ret_irq = IRQ_EPPI2;
110 break;
111 case CH_PIXC_IMAGE:
112 ret_irq = IRQ_PIXC_IN0;
113 break;
114 case CH_PIXC_OVERLAY:
115 ret_irq = IRQ_PIXC_IN1;
116 break;
117 case CH_PIXC_OUTPUT:
118 ret_irq = IRQ_PIXC_OUT;
119 break;
120 case CH_SPORT2_RX:
121 ret_irq = IRQ_SPORT2_RX;
122 break;
123 case CH_SPORT2_TX:
124 ret_irq = IRQ_SPORT2_TX;
125 break;
126 case CH_SPORT3_RX:
127 ret_irq = IRQ_SPORT3_RX;
128 break;
129 case CH_SPORT3_TX:
130 ret_irq = IRQ_SPORT3_TX;
131 break;
132 case CH_SDH:
133 ret_irq = IRQ_SDH;
134 break;
135 case CH_SPI2:
136 ret_irq = IRQ_SPI2;
137 break;
138 case CH_MEM_STREAM0_SRC:
139 case CH_MEM_STREAM0_DEST:
140 ret_irq = IRQ_MDMAS0;
141 break;
142 case CH_MEM_STREAM1_SRC:
143 case CH_MEM_STREAM1_DEST:
144 ret_irq = IRQ_MDMAS1;
145 break;
146 case CH_MEM_STREAM2_SRC:
147 case CH_MEM_STREAM2_DEST:
148 ret_irq = IRQ_MDMAS2;
149 break;
150 case CH_MEM_STREAM3_SRC:
151 case CH_MEM_STREAM3_DEST:
152 ret_irq = IRQ_MDMAS3;
153 break;
154 }
155 return ret_irq;
156}
diff --git a/arch/blackfin/mach-bf548/gpio.c b/arch/blackfin/mach-bf548/gpio.c
new file mode 100644
index 000000000000..0da5f0003b8c
--- /dev/null
+++ b/arch/blackfin/mach-bf548/gpio.c
@@ -0,0 +1,323 @@
1/*
2 * File: arch/blackfin/mach-bf548/gpio.c
3 * Based on:
4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
5 *
6 * Created:
7 * Description: GPIO Abstraction Layer
8 *
9 * Modified:
10 * Copyright 2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/module.h>
31#include <linux/err.h>
32#include <asm/blackfin.h>
33#include <asm/gpio.h>
34#include <asm/portmux.h>
35#include <linux/irq.h>
36
37static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
38 (struct gpio_port_t *)PORTA_FER,
39 (struct gpio_port_t *)PORTB_FER,
40 (struct gpio_port_t *)PORTC_FER,
41 (struct gpio_port_t *)PORTD_FER,
42 (struct gpio_port_t *)PORTE_FER,
43 (struct gpio_port_t *)PORTF_FER,
44 (struct gpio_port_t *)PORTG_FER,
45 (struct gpio_port_t *)PORTH_FER,
46 (struct gpio_port_t *)PORTI_FER,
47 (struct gpio_port_t *)PORTJ_FER,
48};
49
50static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
51static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
52
53inline int check_gpio(unsigned short gpio)
54{
55 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
56 || gpio == GPIO_PH14 || gpio == GPIO_PH15
57 || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
58 || gpio > MAX_BLACKFIN_GPIOS)
59 return -EINVAL;
60 return 0;
61}
62
63inline void portmux_setup(unsigned short portno, unsigned short function)
64{
65 u32 pmux;
66
67 pmux = gpio_array[gpio_bank(portno)]->port_mux;
68
69 pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
70 pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
71
72 gpio_array[gpio_bank(portno)]->port_mux = pmux;
73
74}
75
76inline u16 get_portmux(unsigned short portno)
77{
78 u32 pmux;
79
80 pmux = gpio_array[gpio_bank(portno)]->port_mux;
81
82 return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
83
84}
85
86static void port_setup(unsigned short gpio, unsigned short usage)
87{
88 if (usage == GPIO_USAGE) {
89 if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
90 printk(KERN_WARNING
91 "bfin-gpio: Possible Conflict with Peripheral "
92 "usage and GPIO %d detected!\n", gpio);
93 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
94 } else
95 gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
96 SSYNC();
97}
98
99static int __init bfin_gpio_init(void)
100{
101 printk(KERN_INFO "Blackfin GPIO Controller\n");
102
103 return 0;
104}
105
106arch_initcall(bfin_gpio_init);
107
108int peripheral_request(unsigned short per, const char *label)
109{
110 unsigned long flags;
111 unsigned short ident = P_IDENT(per);
112
113 if (!(per & P_DEFINED))
114 return -ENODEV;
115
116 if (check_gpio(ident) < 0)
117 return -EINVAL;
118
119 local_irq_save(flags);
120
121 if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
122 printk(KERN_ERR
123 "%s: Peripheral %d is already reserved as GPIO!\n",
124 __FUNCTION__, per);
125 dump_stack();
126 local_irq_restore(flags);
127 return -EBUSY;
128 }
129
130 if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
131
132 u16 funct = get_portmux(ident);
133
134 if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
135 printk(KERN_ERR
136 "%s: Peripheral %d is already reserved!\n",
137 __FUNCTION__, per);
138 dump_stack();
139 local_irq_restore(flags);
140 return -EBUSY;
141 }
142 }
143
144 reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
145
146 portmux_setup(ident, P_FUNCT2MUX(per));
147 port_setup(ident, PERIPHERAL_USAGE);
148
149 local_irq_restore(flags);
150
151 return 0;
152}
153EXPORT_SYMBOL(peripheral_request);
154
155int peripheral_request_list(unsigned short per[], const char *label)
156{
157
158 u16 cnt;
159 int ret;
160
161 for (cnt = 0; per[cnt] != 0; cnt++) {
162 ret = peripheral_request(per[cnt], label);
163 if (ret < 0)
164 return ret;
165 }
166
167 return 0;
168}
169EXPORT_SYMBOL(peripheral_request_list);
170
171void peripheral_free(unsigned short per)
172{
173 unsigned long flags;
174 unsigned short ident = P_IDENT(per);
175
176 if (!(per & P_DEFINED))
177 return;
178
179 if (check_gpio(ident) < 0)
180 return;
181
182 local_irq_save(flags);
183
184 if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
185 printk(KERN_ERR "bfin-gpio: Peripheral %d wasn't reserved!\n", per);
186 dump_stack();
187 local_irq_restore(flags);
188 return;
189 }
190
191 if (!(per & P_MAYSHARE)) {
192 port_setup(ident, GPIO_USAGE);
193 }
194
195 reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
196
197 local_irq_restore(flags);
198}
199EXPORT_SYMBOL(peripheral_free);
200
201void peripheral_free_list(unsigned short per[])
202{
203 u16 cnt;
204
205 for (cnt = 0; per[cnt] != 0; cnt++) {
206 peripheral_free(per[cnt]);
207 }
208
209}
210EXPORT_SYMBOL(peripheral_free_list);
211
212/***********************************************************
213*
214* FUNCTIONS: Blackfin GPIO Driver
215*
216* INPUTS/OUTPUTS:
217* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
218*
219*
220* DESCRIPTION: Blackfin GPIO Driver API
221*
222* CAUTION:
223*************************************************************
224* MODIFICATION HISTORY :
225**************************************************************/
226
227int gpio_request(unsigned short gpio, const char *label)
228{
229 unsigned long flags;
230
231 if (check_gpio(gpio) < 0)
232 return -EINVAL;
233
234 local_irq_save(flags);
235
236 if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
237 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
238 dump_stack();
239 local_irq_restore(flags);
240 return -EBUSY;
241 }
242
243 if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
244 printk(KERN_ERR
245 "bfin-gpio: GPIO %d is already reserved as Peripheral!\n", gpio);
246 dump_stack();
247 local_irq_restore(flags);
248 return -EBUSY;
249 }
250
251 reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
252
253 local_irq_restore(flags);
254
255 port_setup(gpio, GPIO_USAGE);
256
257 return 0;
258}
259EXPORT_SYMBOL(gpio_request);
260
261void gpio_free(unsigned short gpio)
262{
263 unsigned long flags;
264
265 if (check_gpio(gpio) < 0)
266 return;
267
268 local_irq_save(flags);
269
270 if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
271 printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
272 dump_stack();
273 local_irq_restore(flags);
274 return;
275 }
276
277 reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
278
279 local_irq_restore(flags);
280}
281EXPORT_SYMBOL(gpio_free);
282
283void gpio_direction_input(unsigned short gpio)
284{
285 unsigned long flags;
286
287 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
288
289 local_irq_save(flags);
290 gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
291 gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
292 local_irq_restore(flags);
293}
294EXPORT_SYMBOL(gpio_direction_input);
295
296void gpio_direction_output(unsigned short gpio)
297{
298 unsigned long flags;
299
300 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
301
302 local_irq_save(flags);
303 gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
304 gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
305 local_irq_restore(flags);
306}
307EXPORT_SYMBOL(gpio_direction_output);
308
309void gpio_set_value(unsigned short gpio, unsigned short arg)
310{
311 if (arg)
312 gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
313 else
314 gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
315
316}
317EXPORT_SYMBOL(gpio_set_value);
318
319unsigned short gpio_get_value(unsigned short gpio)
320{
321 return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
322}
323EXPORT_SYMBOL(gpio_get_value);
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
new file mode 100644
index 000000000000..06751ae8b857
--- /dev/null
+++ b/arch/blackfin/mach-bf548/head.S
@@ -0,0 +1,512 @@
1/*
2 * File: arch/blackfin/mach-bf548/head.S
3 * Based on: arch/blackfin/mach-bf537/head.S
4 * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5 *
6 * Created: 1998
7 * Description: Startup code for Blackfin BF548
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/linkage.h>
31#include <asm/blackfin.h>
32#include <asm/trace.h>
33#if CONFIG_BFIN_KERNEL_CLOCK
34#include <asm/mach/mem_init.h>
35#endif
36
37.global __rambase
38.global __ramstart
39.global __ramend
40.extern ___bss_stop
41.extern ___bss_start
42.extern _bf53x_relocate_l1_mem
43
44#define INITIAL_STACK 0xFFB01000
45
46.text
47
48ENTRY(__start)
49ENTRY(__stext)
50 /* R0: argument of command line string, passed from uboot, save it */
51 R7 = R0;
52 /* Set the SYSCFG register */
53 R0 = 0x36;
54 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
55 R0 = 0;
56
57 /* Clear Out All the data and pointer Registers*/
58 R1 = R0;
59 R2 = R0;
60 R3 = R0;
61 R4 = R0;
62 R5 = R0;
63 R6 = R0;
64
65 P0 = R0;
66 P1 = R0;
67 P2 = R0;
68 P3 = R0;
69 P4 = R0;
70 P5 = R0;
71
72 LC0 = r0;
73 LC1 = r0;
74 L0 = r0;
75 L1 = r0;
76 L2 = r0;
77 L3 = r0;
78
79 /* Clear Out All the DAG Registers*/
80 B0 = r0;
81 B1 = r0;
82 B2 = r0;
83 B3 = r0;
84
85 I0 = r0;
86 I1 = r0;
87 I2 = r0;
88 I3 = r0;
89
90 M0 = r0;
91 M1 = r0;
92 M2 = r0;
93 M3 = r0;
94
95 trace_buffer_start(p0,r0);
96 P0 = R1;
97 R0 = R1;
98
99 /* Turn off the icache */
100 p0.l = (IMEM_CONTROL & 0xFFFF);
101 p0.h = (IMEM_CONTROL >> 16);
102 R1 = [p0];
103 R0 = ~ENICPLB;
104 R0 = R0 & R1;
105 [p0] = R0;
106 SSYNC;
107
108 /* Turn off the dcache */
109 p0.l = (DMEM_CONTROL & 0xFFFF);
110 p0.h = (DMEM_CONTROL >> 16);
111 R1 = [p0];
112 R0 = ~ENDCPLB;
113 R0 = R0 & R1;
114 [p0] = R0;
115 SSYNC;
116
117 /* Initialize stack pointer */
118 SP.L = LO(INITIAL_STACK);
119 SP.H = HI(INITIAL_STACK);
120 FP = SP;
121 USP = SP;
122
123 /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
124 call _bf53x_relocate_l1_mem;
125#if CONFIG_BFIN_KERNEL_CLOCK
126 call _start_dma_code;
127#endif
128 /* Code for initializing Async memory banks */
129
130 p2.h = hi(EBIU_AMBCTL1);
131 p2.l = lo(EBIU_AMBCTL1);
132 r0.h = hi(AMBCTL1VAL);
133 r0.l = lo(AMBCTL1VAL);
134 [p2] = r0;
135 ssync;
136
137 p2.h = hi(EBIU_AMBCTL0);
138 p2.l = lo(EBIU_AMBCTL0);
139 r0.h = hi(AMBCTL0VAL);
140 r0.l = lo(AMBCTL0VAL);
141 [p2] = r0;
142 ssync;
143
144 p2.h = hi(EBIU_AMGCTL);
145 p2.l = lo(EBIU_AMGCTL);
146 r0 = AMGCTLVAL;
147 w[p2] = r0;
148 ssync;
149
150 /* This section keeps the processor in supervisor mode
151 * during kernel boot. Switches to user mode at end of boot.
152 * See page 3-9 of Hardware Reference manual for documentation.
153 */
154
155 /* EVT15 = _real_start */
156
157 p0.l = lo(EVT15);
158 p0.h = hi(EVT15);
159 p1.l = _real_start;
160 p1.h = _real_start;
161 [p0] = p1;
162 csync;
163
164 p0.l = lo(IMASK);
165 p0.h = hi(IMASK);
166 p1.l = IMASK_IVG15;
167 p1.h = 0x0;
168 [p0] = p1;
169 csync;
170
171 raise 15;
172 p0.l = .LWAIT_HERE;
173 p0.h = .LWAIT_HERE;
174 reti = p0;
175#if defined (ANOMALY_05000281)
176 nop;
177 nop;
178 nop;
179#endif
180 rti;
181
182.LWAIT_HERE:
183 jump .LWAIT_HERE;
184
185ENTRY(_real_start)
186 [ -- sp ] = reti;
187 p0.l = lo(WDOG_CTL);
188 p0.h = hi(WDOG_CTL);
189 r0 = 0xAD6(z);
190 w[p0] = r0; /* watchdog off for now */
191 ssync;
192
193 /* Code update for BSS size == 0
194 * Zero out the bss region.
195 */
196
197 p1.l = ___bss_start;
198 p1.h = ___bss_start;
199 p2.l = ___bss_stop;
200 p2.h = ___bss_stop;
201 r0 = 0;
202 p2 -= p1;
203 lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
204.L_clear_bss:
205 B[p1++] = r0;
206
207 /* In case there is a NULL pointer reference
208 * Zero out region before stext
209 */
210
211 p1.l = 0x0;
212 p1.h = 0x0;
213 r0.l = __stext;
214 r0.h = __stext;
215 r0 = r0 >> 1;
216 p2 = r0;
217 r0 = 0;
218 lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
219.L_clear_zero:
220 W[p1++] = r0;
221
222 /* pass the uboot arguments to the global value command line */
223 R0 = R7;
224 call _cmdline_init;
225
226 p1.l = __rambase;
227 p1.h = __rambase;
228 r0.l = __sdata;
229 r0.h = __sdata;
230 [p1] = r0;
231
232 p1.l = __ramstart;
233 p1.h = __ramstart;
234 p3.l = ___bss_stop;
235 p3.h = ___bss_stop;
236
237 r1 = p3;
238 [p1] = r1;
239
240
241 /*
242 * load the current thread pointer and stack
243 */
244 r1.l = _init_thread_union;
245 r1.h = _init_thread_union;
246
247 r2.l = 0x2000;
248 r2.h = 0x0000;
249 r1 = r1 + r2;
250 sp = r1;
251 usp = sp;
252 fp = sp;
253 call _start_kernel;
254.L_exit:
255 jump.s .L_exit;
256
257.section .l1.text
258#if CONFIG_BFIN_KERNEL_CLOCK
259ENTRY(_start_dma_code)
260
261 /* Enable PHY CLK buffer output */
262 p0.h = hi(VR_CTL);
263 p0.l = lo(VR_CTL);
264 r0.l = w[p0];
265 bitset(r0, 14);
266 w[p0] = r0.l;
267 ssync;
268
269 p0.h = hi(SIC_IWR);
270 p0.l = lo(SIC_IWR);
271 r0.l = 0x1;
272 r0.h = 0x0;
273 [p0] = r0;
274 SSYNC;
275
276 /*
277 * Set PLL_CTL
278 * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
279 * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
280 * - [7] = output delay (add 200ps of delay to mem signals)
281 * - [6] = input delay (add 200ps of input delay to mem signals)
282 * - [5] = PDWN : 1=All Clocks off
283 * - [3] = STOPCK : 1=Core Clock off
284 * - [1] = PLL_OFF : 1=Disable Power to PLL
285 * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
286 * all other bits set to zero
287 */
288
289 p0.h = hi(PLL_LOCKCNT);
290 p0.l = lo(PLL_LOCKCNT);
291 r0 = 0x300(Z);
292 w[p0] = r0.l;
293 ssync;
294
295 P2.H = hi(EBIU_SDGCTL);
296 P2.L = lo(EBIU_SDGCTL);
297 R0 = [P2];
298 BITSET (R0, 24);
299 [P2] = R0;
300 SSYNC;
301
302 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
303 r0 = r0 << 9; /* Shift it over, */
304 r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
305 r0 = r1 | r0;
306 r1 = PLL_BYPASS; /* Bypass the PLL? */
307 r1 = r1 << 8; /* Shift it over */
308 r0 = r1 | r0; /* add them all together */
309
310 p0.h = hi(PLL_CTL);
311 p0.l = lo(PLL_CTL); /* Load the address */
312 cli r2; /* Disable interrupts */
313 ssync;
314 w[p0] = r0.l; /* Set the value */
315 idle; /* Wait for the PLL to stablize */
316 sti r2; /* Enable interrupts */
317
318.Lcheck_again:
319 p0.h = hi(PLL_STAT);
320 p0.l = lo(PLL_STAT);
321 R0 = W[P0](Z);
322 CC = BITTST(R0,5);
323 if ! CC jump .Lcheck_again;
324
325 /* Configure SCLK & CCLK Dividers */
326 r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
327 p0.h = hi(PLL_DIV);
328 p0.l = lo(PLL_DIV);
329 w[p0] = r0.l;
330 ssync;
331
332 p0.l = lo(EBIU_SDRRC);
333 p0.h = hi(EBIU_SDRRC);
334 r0 = mem_SDRRC;
335 w[p0] = r0.l;
336 ssync;
337
338 p0.l = (EBIU_SDBCTL & 0xFFFF);
339 p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
340 r0 = mem_SDBCTL;
341 w[p0] = r0.l;
342 ssync;
343
344 P2.H = hi(EBIU_SDGCTL);
345 P2.L = lo(EBIU_SDGCTL);
346 R0 = [P2];
347 BITCLR (R0, 24);
348 p0.h = hi(EBIU_SDSTAT);
349 p0.l = lo(EBIU_SDSTAT);
350 r2.l = w[p0];
351 cc = bittst(r2,3);
352 if !cc jump .Lskip;
353 NOP;
354 BITSET (R0, 23);
355.Lskip:
356 [P2] = R0;
357 SSYNC;
358
359 R0.L = lo(mem_SDGCTL);
360 R0.H = hi(mem_SDGCTL);
361 R1 = [p2];
362 R1 = R1 | R0;
363 [P2] = R1;
364 SSYNC;
365
366 p0.h = hi(SIC_IWR);
367 p0.l = lo(SIC_IWR);
368 r0.l = lo(IWR_ENABLE_ALL);
369 r0.h = hi(IWR_ENABLE_ALL);
370 [p0] = r0;
371 SSYNC;
372
373 RTS;
374#endif /* CONFIG_BFIN_KERNEL_CLOCK */
375
376ENTRY(_bfin_reset)
377 /* No more interrupts to be handled*/
378 CLI R6;
379 SSYNC;
380
381#if defined(CONFIG_MTD_M25P80)
382/*
383 * The following code fix the SPI flash reboot issue,
384 * /CS signal of the chip which is using PF10 return to GPIO mode
385 */
386 p0.h = hi(PORTF_FER);
387 p0.l = lo(PORTF_FER);
388 r0.l = 0x0000;
389 w[p0] = r0.l;
390 SSYNC;
391
392/* /CS return to high */
393 p0.h = hi(PORTFIO);
394 p0.l = lo(PORTFIO);
395 r0.l = 0xFFFF;
396 w[p0] = r0.l;
397 SSYNC;
398
399/* Delay some time, This is necessary */
400 r1.h = 0;
401 r1.l = 0x400;
402 p1 = r1;
403 lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
404_delay_lab1:
405 r0.h = 0;
406 r0.l = 0x8000;
407 p0 = r0;
408 lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
409_delay_lab0:
410 nop;
411_delay_lab0_end:
412 nop;
413_delay_lab1_end:
414 nop;
415#endif
416
417 /* Clear the bits 13-15 in SWRST if they werent cleared */
418 p0.h = hi(SWRST);
419 p0.l = lo(SWRST);
420 csync;
421 r0.l = w[p0];
422
423 /* Clear the IMASK register */
424 p0.h = hi(IMASK);
425 p0.l = lo(IMASK);
426 r0 = 0x0;
427 [p0] = r0;
428
429 /* Clear the ILAT register */
430 p0.h = hi(ILAT);
431 p0.l = lo(ILAT);
432 r0 = [p0];
433 [p0] = r0;
434 SSYNC;
435
436 /* Disable the WDOG TIMER */
437 p0.h = hi(WDOG_CTL);
438 p0.l = lo(WDOG_CTL);
439 r0.l = 0xAD6;
440 w[p0] = r0.l;
441 SSYNC;
442
443 /* Clear the sticky bit incase it is already set */
444 p0.h = hi(WDOG_CTL);
445 p0.l = lo(WDOG_CTL);
446 r0.l = 0x8AD6;
447 w[p0] = r0.l;
448 SSYNC;
449
450 /* Program the count value */
451 R0.l = 0x100;
452 R0.h = 0x0;
453 P0.h = hi(WDOG_CNT);
454 P0.l = lo(WDOG_CNT);
455 [P0] = R0;
456 SSYNC;
457
458 /* Program WDOG_STAT if necessary */
459 P0.h = hi(WDOG_CTL);
460 P0.l = lo(WDOG_CTL);
461 R0 = W[P0](Z);
462 CC = BITTST(R0,1);
463 if !CC JUMP .LWRITESTAT;
464 CC = BITTST(R0,2);
465 if !CC JUMP .LWRITESTAT;
466 JUMP .LSKIP_WRITE;
467
468.LWRITESTAT:
469 /* When watch dog timer is enabled,
470 * a write to STAT will load the contents of CNT to STAT
471 */
472 R0 = 0x0000(z);
473 P0.h = hi(WDOG_STAT);
474 P0.l = lo(WDOG_STAT)
475 [P0] = R0;
476 SSYNC;
477
478.LSKIP_WRITE:
479 /* Enable the reset event */
480 P0.h = hi(WDOG_CTL);
481 P0.l = lo(WDOG_CTL);
482 R0 = W[P0](Z);
483 BITCLR(R0,1);
484 BITCLR(R0,2);
485 W[P0] = R0.L;
486 SSYNC;
487 NOP;
488
489 /* Enable the wdog counter */
490 R0 = W[P0](Z);
491 BITCLR(R0,4);
492 W[P0] = R0.L;
493 SSYNC;
494
495 IDLE;
496
497 RTS;
498
499.data
500
501/*
502 * Set up the usable of RAM stuff. Size of RAM is determined then
503 * an initial stack set up at the end.
504 */
505
506.align 4
507__rambase:
508.long 0
509__ramstart:
510.long 0
511__ramend:
512.long 0
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
new file mode 100644
index 000000000000..cb0ebac53c79
--- /dev/null
+++ b/arch/blackfin/mach-bf548/ints-priority.c
@@ -0,0 +1,137 @@
1/*
2 * File: arch/blackfin/mach-bf537/ints-priority.c
3 * Based on: arch/blackfin/mach-bf533/ints-priority.c
4 * Author: Michael Hennerich
5 *
6 * Created:
7 * Description: Set up the interupt priorities
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/module.h>
31#include <linux/irq.h>
32#include <asm/blackfin.h>
33
34void program_IAR(void)
35{
36 /* Program the IAR0 Register with the configured priority */
37 bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
38 ((CONFIG_IRQ_DMAC0_ERR - 7) << IRQ_DMAC0_ERR_POS) |
39 ((CONFIG_IRQ_EPPI0_ERR - 7) << IRQ_EPPI0_ERR_POS) |
40 ((CONFIG_IRQ_SPORT0_ERR - 7) << IRQ_SPORT0_ERR_POS) |
41 ((CONFIG_IRQ_SPORT1_ERR - 7) << IRQ_SPORT1_ERR_POS) |
42 ((CONFIG_IRQ_SPI0_ERR - 7) << IRQ_SPI0_ERR_POS) |
43 ((CONFIG_IRQ_UART0_ERR - 7) << IRQ_UART0_ERR_POS) |
44 ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS));
45
46 bfin_write_SIC_IAR1(((CONFIG_IRQ_EPPI0 - 7) << IRQ_EPPI0_POS) |
47 ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
48 ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
49 ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS) |
50 ((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
51 ((CONFIG_IRQ_SPI0 - 7) << IRQ_SPI0_POS) |
52 ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
53 ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
54
55 bfin_write_SIC_IAR2(((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
56 ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) |
57 ((CONFIG_IRQ_PINT0 - 7) << IRQ_PINT0_POS) |
58 ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) |
59 ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) |
60 ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) |
61 ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS));
62
63 bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) |
64 ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) |
65 ((CONFIG_IRQ_SPORT3_ERR - 7) << IRQ_SPORT3_ERR_POS) |
66 ((CONFIG_IRQ_MXVR_DATA - 7) << IRQ_MXVR_DATA_POS) |
67 ((CONFIG_IRQ_SPI1_ERR - 7) << IRQ_SPI1_ERR_POS) |
68 ((CONFIG_IRQ_SPI2_ERR - 7) << IRQ_SPI2_ERR_POS) |
69 ((CONFIG_IRQ_UART1_ERR - 7) << IRQ_UART1_ERR_POS) |
70 ((CONFIG_IRQ_UART2_ERR - 7) << IRQ_UART2_ERR_POS));
71
72 bfin_write_SIC_IAR4(((CONFIG_IRQ_CAN0_ERR - 7) << IRQ_CAN0_ERR_POS) |
73 ((CONFIG_IRQ_SPORT2_RX - 7) << IRQ_SPORT2_RX_POS) |
74 ((CONFIG_IRQ_SPORT2_TX - 7) << IRQ_SPORT2_TX_POS) |
75 ((CONFIG_IRQ_SPORT3_RX - 7) << IRQ_SPORT3_RX_POS) |
76 ((CONFIG_IRQ_SPORT3_TX - 7) << IRQ_SPORT3_TX_POS) |
77 ((CONFIG_IRQ_EPPI1 - 7) << IRQ_EPPI1_POS) |
78 ((CONFIG_IRQ_EPPI2 - 7) << IRQ_EPPI2_POS) |
79 ((CONFIG_IRQ_SPI1 - 7) << IRQ_SPI1_POS));
80
81 bfin_write_SIC_IAR5(((CONFIG_IRQ_SPI2 - 7) << IRQ_SPI2_POS) |
82 ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
83 ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
84 ((CONFIG_IRQ_ATAPI_RX - 7) << IRQ_ATAPI_RX_POS) |
85 ((CONFIG_IRQ_ATAPI_TX - 7) << IRQ_ATAPI_TX_POS) |
86 ((CONFIG_IRQ_TWI0 - 7) << IRQ_TWI0_POS) |
87 ((CONFIG_IRQ_TWI1 - 7) << IRQ_TWI1_POS) |
88 ((CONFIG_IRQ_CAN0_RX - 7) << IRQ_CAN0_RX_POS));
89
90 bfin_write_SIC_IAR6(((CONFIG_IRQ_CAN0_TX - 7) << IRQ_CAN0_TX_POS) |
91 ((CONFIG_IRQ_MDMAS2 - 7) << IRQ_MDMAS2_POS) |
92 ((CONFIG_IRQ_MDMAS3 - 7) << IRQ_MDMAS3_POS) |
93 ((CONFIG_IRQ_MXVR_ERR - 7) << IRQ_MXVR_ERR_POS) |
94 ((CONFIG_IRQ_MXVR_MSG - 7) << IRQ_MXVR_MSG_POS) |
95 ((CONFIG_IRQ_MXVR_PKT - 7) << IRQ_MXVR_PKT_POS) |
96 ((CONFIG_IRQ_EPPI1_ERR - 7) << IRQ_EPPI1_ERR_POS) |
97 ((CONFIG_IRQ_EPPI2_ERR - 7) << IRQ_EPPI2_ERR_POS));
98
99 bfin_write_SIC_IAR7(((CONFIG_IRQ_UART3_ERR - 7) << IRQ_UART3_ERR_POS) |
100 ((CONFIG_IRQ_HOST_ERR - 7) << IRQ_HOST_ERR_POS) |
101 ((CONFIG_IRQ_PIXC_ERR - 7) << IRQ_PIXC_ERR_POS) |
102 ((CONFIG_IRQ_NFC_ERR - 7) << IRQ_NFC_ERR_POS) |
103 ((CONFIG_IRQ_ATAPI_ERR - 7) << IRQ_ATAPI_ERR_POS) |
104 ((CONFIG_IRQ_CAN1_ERR - 7) << IRQ_CAN1_ERR_POS) |
105 ((CONFIG_IRQ_HS_DMA_ERR - 7) << IRQ_HS_DMA_ERR_POS));
106
107 bfin_write_SIC_IAR8(((CONFIG_IRQ_PIXC_IN0 - 7) << IRQ_PIXC_IN1_POS) |
108 ((CONFIG_IRQ_PIXC_IN1 - 7) << IRQ_PIXC_IN1_POS) |
109 ((CONFIG_IRQ_PIXC_OUT - 7) << IRQ_PIXC_OUT_POS) |
110 ((CONFIG_IRQ_SDH - 7) << IRQ_SDH_POS) |
111 ((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
112 ((CONFIG_IRQ_KEY - 7) << IRQ_KEY_POS) |
113 ((CONFIG_IRQ_CAN1_RX - 7) << IRQ_CAN1_RX_POS) |
114 ((CONFIG_IRQ_CAN1_TX - 7) << IRQ_CAN1_TX_POS));
115
116 bfin_write_SIC_IAR9(((CONFIG_IRQ_SDH_MASK0 - 7) << IRQ_SDH_MASK0_POS) |
117 ((CONFIG_IRQ_SDH_MASK1 - 7) << IRQ_SDH_MASK1_POS) |
118 ((CONFIG_IRQ_USB_INT0 - 7) << IRQ_USB_INT0_POS) |
119 ((CONFIG_IRQ_USB_INT1 - 7) << IRQ_USB_INT1_POS) |
120 ((CONFIG_IRQ_USB_INT2 - 7) << IRQ_USB_INT2_POS) |
121 ((CONFIG_IRQ_USB_DMA - 7) << IRQ_USB_DMA_POS) |
122 ((CONFIG_IRQ_OTPSEC - 7) << IRQ_OTPSEC_POS));
123
124 bfin_write_SIC_IAR10(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
125 ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS));
126
127 bfin_write_SIC_IAR11(((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
128 ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
129 ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS) |
130 ((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
131 ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
132 ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
133 ((CONFIG_IRQ_PINT2 - 7) << IRQ_PINT2_POS) |
134 ((CONFIG_IRQ_PINT3 - 7) << IRQ_PINT3_POS));
135
136 SSYNC();
137}
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
index 57f475a55161..f39235a55783 100644
--- a/arch/blackfin/mach-bf561/Makefile
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -4,6 +4,6 @@
4 4
5extra-y := head.o 5extra-y := head.o
6 6
7obj-y := ints-priority.o 7obj-y := ints-priority.o dma.o
8 8
9obj-$(CONFIG_BF561_COREB) += coreb.o 9obj-$(CONFIG_BF561_COREB) += coreb.o
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 3dc5c042048c..5b2b544529a1 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -34,7 +34,7 @@
34#include <linux/spi/spi.h> 34#include <linux/spi/spi.h>
35#include <linux/spi/flash.h> 35#include <linux/spi/flash.h>
36#include <linux/usb_isp1362.h> 36#include <linux/usb_isp1362.h>
37#include <asm/irq.h> 37#include <linux/irq.h>
38#include <asm/bfin5xx_spi.h> 38#include <asm/bfin5xx_spi.h>
39 39
40/* 40/*
@@ -52,11 +52,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
52 .size = 0x00020000, 52 .size = 0x00020000,
53 .offset = 0, 53 .offset = 0,
54 .mask_flags = MTD_CAP_ROM 54 .mask_flags = MTD_CAP_ROM
55 },{ 55 }, {
56 .name = "kernel", 56 .name = "kernel",
57 .size = 0xe0000, 57 .size = 0xe0000,
58 .offset = 0x20000 58 .offset = 0x20000
59 },{ 59 }, {
60 .name = "file system", 60 .name = "file system",
61 .size = 0x700000, 61 .size = 0x700000,
62 .offset = 0x00100000, 62 .offset = 0x00100000,
@@ -186,7 +186,7 @@ static struct resource smc91x_resources[] = {
186 .start = 0x28000300, 186 .start = 0x28000300,
187 .end = 0x28000300 + 16, 187 .end = 0x28000300 + 16,
188 .flags = IORESOURCE_MEM, 188 .flags = IORESOURCE_MEM,
189 },{ 189 }, {
190 .start = IRQ_PF0, 190 .start = IRQ_PF0,
191 .end = IRQ_PF0, 191 .end = IRQ_PF0,
192 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 192 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -206,11 +206,11 @@ static struct resource isp1362_hcd_resources[] = {
206 .start = 0x24008000, 206 .start = 0x24008000,
207 .end = 0x24008000, 207 .end = 0x24008000,
208 .flags = IORESOURCE_MEM, 208 .flags = IORESOURCE_MEM,
209 },{ 209 }, {
210 .start = 0x24008004, 210 .start = 0x24008004,
211 .end = 0x24008004, 211 .end = 0x24008004,
212 .flags = IORESOURCE_MEM, 212 .flags = IORESOURCE_MEM,
213 },{ 213 }, {
214 .start = IRQ_PF47, 214 .start = IRQ_PF47,
215 .end = IRQ_PF47, 215 .end = IRQ_PF47,
216 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 216 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -241,25 +241,25 @@ static struct platform_device isp1362_hcd_device = {
241 241
242#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 242#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
243static struct resource bfin_uart_resources[] = { 243static struct resource bfin_uart_resources[] = {
244 { 244 {
245 .start = 0xFFC00400, 245 .start = 0xFFC00400,
246 .end = 0xFFC004FF, 246 .end = 0xFFC004FF,
247 .flags = IORESOURCE_MEM, 247 .flags = IORESOURCE_MEM,
248 }, 248 },
249}; 249};
250 250
251static struct platform_device bfin_uart_device = { 251static struct platform_device bfin_uart_device = {
252 .name = "bfin-uart", 252 .name = "bfin-uart",
253 .id = 1, 253 .id = 1,
254 .num_resources = ARRAY_SIZE(bfin_uart_resources), 254 .num_resources = ARRAY_SIZE(bfin_uart_resources),
255 .resource = bfin_uart_resources, 255 .resource = bfin_uart_resources,
256}; 256};
257#endif 257#endif
258 258
259static struct platform_device *cm_bf561_devices[] __initdata = { 259static struct platform_device *cm_bf561_devices[] __initdata = {
260 260
261#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 261#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
262 &bfin_uart_device, 262 &bfin_uart_device,
263#endif 263#endif
264 264
265#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 265#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 9720b5c307ab..724191da20a2 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -30,10 +30,9 @@
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/spi/spi.h> 32#include <linux/spi/spi.h>
33#include <asm/irq.h>
34#include <asm/bfin5xx_spi.h>
35#include <linux/interrupt.h>
36#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/interrupt.h>
35#include <asm/bfin5xx_spi.h>
37 36
38/* 37/*
39 * Name the Board for the /proc/cpuinfo 38 * Name the Board for the /proc/cpuinfo
@@ -45,13 +44,13 @@ char *bfin_board_name = "ADDS-BF561-EZKIT";
45 44
46#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) 45#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
47static struct resource bfin_isp1761_resources[] = { 46static struct resource bfin_isp1761_resources[] = {
48 [0] = { 47 {
49 .name = "isp1761-regs", 48 .name = "isp1761-regs",
50 .start = ISP1761_BASE + 0x00000000, 49 .start = ISP1761_BASE + 0x00000000,
51 .end = ISP1761_BASE + 0x000fffff, 50 .end = ISP1761_BASE + 0x000fffff,
52 .flags = IORESOURCE_MEM, 51 .flags = IORESOURCE_MEM,
53 }, 52 },
54 [1] = { 53 {
55 .start = ISP1761_IRQ, 54 .start = ISP1761_IRQ,
56 .end = ISP1761_IRQ, 55 .end = ISP1761_IRQ,
57 .flags = IORESOURCE_IRQ, 56 .flags = IORESOURCE_IRQ,
@@ -71,7 +70,7 @@ static struct platform_device *bfin_isp1761_devices[] = {
71 70
72int __init bfin_isp1761_init(void) 71int __init bfin_isp1761_init(void)
73{ 72{
74 unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices); 73 unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
75 74
76 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); 75 printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
77 set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); 76 set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -98,7 +97,7 @@ static struct resource smc91x_resources[] = {
98 .start = 0x2C010300, 97 .start = 0x2C010300,
99 .end = 0x2C010300 + 16, 98 .end = 0x2C010300 + 16,
100 .flags = IORESOURCE_MEM, 99 .flags = IORESOURCE_MEM,
101 },{ 100 }, {
102 101
103 .start = IRQ_PF9, 102 .start = IRQ_PF9,
104 .end = IRQ_PF9, 103 .end = IRQ_PF9,
@@ -116,18 +115,18 @@ static struct platform_device smc91x_device = {
116 115
117#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 116#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
118static struct resource bfin_uart_resources[] = { 117static struct resource bfin_uart_resources[] = {
119 { 118 {
120 .start = 0xFFC00400, 119 .start = 0xFFC00400,
121 .end = 0xFFC004FF, 120 .end = 0xFFC004FF,
122 .flags = IORESOURCE_MEM, 121 .flags = IORESOURCE_MEM,
123 }, 122 },
124}; 123};
125 124
126static struct platform_device bfin_uart_device = { 125static struct platform_device bfin_uart_device = {
127 .name = "bfin-uart", 126 .name = "bfin-uart",
128 .id = 1, 127 .id = 1,
129 .num_resources = ARRAY_SIZE(bfin_uart_resources), 128 .num_resources = ARRAY_SIZE(bfin_uart_resources),
130 .resource = bfin_uart_resources, 129 .resource = bfin_uart_resources,
131}; 130};
132#endif 131#endif
133 132
@@ -176,7 +175,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
176 &spi_bfin_master_device, 175 &spi_bfin_master_device,
177#endif 176#endif
178#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 177#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
179 &bfin_uart_device, 178 &bfin_uart_device,
180#endif 179#endif
181}; 180};
182 181
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
index 585ecdd2f6a5..4dfea5da674c 100644
--- a/arch/blackfin/mach-bf561/boards/generic_board.c
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -30,7 +30,7 @@
30 30
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <asm/irq.h> 33#include <linux/irq.h>
34 34
35char *bfin_board_name = "UNKNOWN BOARD"; 35char *bfin_board_name = "UNKNOWN BOARD";
36 36
@@ -43,11 +43,11 @@ static struct resource smc91x_resources[] = {
43 .start = 0x2C010300, 43 .start = 0x2C010300,
44 .end = 0x2C010300 + 16, 44 .end = 0x2C010300 + 16,
45 .flags = IORESOURCE_MEM, 45 .flags = IORESOURCE_MEM,
46 },{ 46 }, {
47 .start = IRQ_PROG_INTB, 47 .start = IRQ_PROG_INTB,
48 .end = IRQ_PROG_INTB, 48 .end = IRQ_PROG_INTB,
49 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, 49 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
50 },{ 50 }, {
51 /* 51 /*
52 * denotes the flag pin and is used directly if 52 * denotes the flag pin and is used directly if
53 * CONFIG_IRQCHIP_DEMUX_GPIO is defined. 53 * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index db308c7ccabb..c442eb23db5e 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <asm/irq.h> 17#include <linux/irq.h>
18 18
19char *bfin_board_name = "Tepla-BF561"; 19char *bfin_board_name = "Tepla-BF561";
20 20
@@ -26,11 +26,11 @@ static struct resource smc91x_resources[] = {
26 .start = 0x2C000300, 26 .start = 0x2C000300,
27 .end = 0x2C000320, 27 .end = 0x2C000320,
28 .flags = IORESOURCE_MEM, 28 .flags = IORESOURCE_MEM,
29 },{ 29 }, {
30 .start = IRQ_PROG_INTB, 30 .start = IRQ_PROG_INTB,
31 .end = IRQ_PROG_INTB, 31 .end = IRQ_PROG_INTB,
32 .flags = IORESOURCE_IRQ|IORESOURCE_IRQ_HIGHLEVEL, 32 .flags = IORESOURCE_IRQ|IORESOURCE_IRQ_HIGHLEVEL,
33 },{ 33 }, {
34 /* 34 /*
35 * denotes the flag pin and is used directly if 35 * denotes the flag pin and is used directly if
36 * CONFIG_IRQCHIP_DEMUX_GPIO is defined. 36 * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index b28582fe083c..5d1d21b4c2a7 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -32,8 +32,8 @@
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/uaccess.h>
35#include <asm/dma.h> 36#include <asm/dma.h>
36#include <asm/uaccess.h>
37 37
38#define MODULE_VER "v0.1" 38#define MODULE_VER "v0.1"
39 39
@@ -202,7 +202,7 @@ static int coreb_open(struct inode *inode, struct file *file)
202 spin_unlock_irq(&coreb_lock); 202 spin_unlock_irq(&coreb_lock);
203 return 0; 203 return 0;
204 204
205 out_busy: 205 out_busy:
206 spin_unlock_irq(&coreb_lock); 206 spin_unlock_irq(&coreb_lock);
207 return -EBUSY; 207 return -EBUSY;
208} 208}
@@ -365,19 +365,19 @@ int __init bf561_coreb_init(void)
365 printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER); 365 printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
366 return 0; 366 return 0;
367 367
368 release_dma_src: 368 release_dma_src:
369 free_dma(CH_MEM_STREAM2_SRC); 369 free_dma(CH_MEM_STREAM2_SRC);
370 release_dma_dest: 370 release_dma_dest:
371 free_dma(CH_MEM_STREAM2_DEST); 371 free_dma(CH_MEM_STREAM2_DEST);
372 release_data_a_sram: 372 release_data_a_sram:
373 release_mem_region(0xff400000, 0x8000); 373 release_mem_region(0xff400000, 0x8000);
374 release_data_b_sram: 374 release_data_b_sram:
375 release_mem_region(0xff500000, 0x8000); 375 release_mem_region(0xff500000, 0x8000);
376 release_instruction_b_sram: 376 release_instruction_b_sram:
377 release_mem_region(0xff610000, 0x4000); 377 release_mem_region(0xff610000, 0x4000);
378 release_instruction_a_sram: 378 release_instruction_a_sram:
379 release_mem_region(0xff600000, 0x4000); 379 release_mem_region(0xff600000, 0x4000);
380 exit: 380 exit:
381 return -ENOMEM; 381 return -ENOMEM;
382} 382}
383 383
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
new file mode 100644
index 000000000000..89c65bb0bed3
--- /dev/null
+++ b/arch/blackfin/mach-bf561/dma.c
@@ -0,0 +1,131 @@
1/*
2 * File: arch/blackfin/mach-bf561/dma.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29#include <asm/blackfin.h>
30#include <asm/dma.h>
31
32struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
33 (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
34 (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
35 (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
36 (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
37 (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
38 (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
39 (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
40 (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
41 (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
42 (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
43 (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
44 (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
45 (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
46 (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
47 (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
48 (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
49 (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
50 (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
51 (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
52 (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
53 (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
54 (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
55 (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
56 (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
57 (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
58 (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
59 (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
60 (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
61 (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
62 (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
63 (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
64 (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
65 (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
66 (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
67 (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
68 (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
69};
70
71int channel2irq(unsigned int channel)
72{
73 int ret_irq = -1;
74
75 switch (channel) {
76 case CH_PPI0:
77 ret_irq = IRQ_PPI0;
78 break;
79 case CH_PPI1:
80 ret_irq = IRQ_PPI1;
81 break;
82 case CH_SPORT0_RX:
83 ret_irq = IRQ_SPORT0_RX;
84 break;
85 case CH_SPORT0_TX:
86 ret_irq = IRQ_SPORT0_TX;
87 break;
88 case CH_SPORT1_RX:
89 ret_irq = IRQ_SPORT1_RX;
90 break;
91 case CH_SPORT1_TX:
92 ret_irq = IRQ_SPORT1_TX;
93 break;
94 case CH_SPI:
95 ret_irq = IRQ_SPI;
96 break;
97 case CH_UART_RX:
98 ret_irq = IRQ_UART_RX;
99 break;
100 case CH_UART_TX:
101 ret_irq = IRQ_UART_TX;
102 break;
103
104 case CH_MEM_STREAM0_SRC:
105 case CH_MEM_STREAM0_DEST:
106 ret_irq = IRQ_MEM_DMA0;
107 break;
108 case CH_MEM_STREAM1_SRC:
109 case CH_MEM_STREAM1_DEST:
110 ret_irq = IRQ_MEM_DMA1;
111 break;
112 case CH_MEM_STREAM2_SRC:
113 case CH_MEM_STREAM2_DEST:
114 ret_irq = IRQ_MEM_DMA2;
115 break;
116 case CH_MEM_STREAM3_SRC:
117 case CH_MEM_STREAM3_DEST:
118 ret_irq = IRQ_MEM_DMA3;
119 break;
120
121 case CH_IMEM_STREAM0_SRC:
122 case CH_IMEM_STREAM0_DEST:
123 ret_irq = IRQ_IMEM_DMA0;
124 break;
125 case CH_IMEM_STREAM1_SRC:
126 case CH_IMEM_STREAM1_DEST:
127 ret_irq = IRQ_IMEM_DMA1;
128 break;
129 }
130 return ret_irq;
131}
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
index 31cbc75c85cf..2f08bcb2dded 100644
--- a/arch/blackfin/mach-bf561/head.S
+++ b/arch/blackfin/mach-bf561/head.S
@@ -30,6 +30,8 @@
30#include <linux/linkage.h> 30#include <linux/linkage.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <asm/blackfin.h> 32#include <asm/blackfin.h>
33#include <asm/trace.h>
34
33#if CONFIG_BFIN_KERNEL_CLOCK 35#if CONFIG_BFIN_KERNEL_CLOCK
34#include <asm/mach/mem_init.h> 36#include <asm/mach/mem_init.h>
35#endif 37#endif
@@ -93,6 +95,10 @@ ENTRY(__start)
93 M2 = r0; 95 M2 = r0;
94 M3 = r0; 96 M3 = r0;
95 97
98 trace_buffer_start(p0,r0);
99 P0 = R1;
100 R0 = R1;
101
96 /* Turn off the icache */ 102 /* Turn off the icache */
97 p0.l = (IMEM_CONTROL & 0xFFFF); 103 p0.l = (IMEM_CONTROL & 0xFFFF);
98 p0.h = (IMEM_CONTROL >> 16); 104 p0.h = (IMEM_CONTROL >> 16);
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
index 86e3b0ee93f4..09b541b0f7c2 100644
--- a/arch/blackfin/mach-bf561/ints-priority.c
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -28,8 +28,8 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/irq.h>
31#include <asm/blackfin.h> 32#include <asm/blackfin.h>
32#include <asm/irq.h>
33 33
34void program_IAR(void) 34void program_IAR(void)
35{ 35{
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index d3a49073d196..0279ede70392 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -4,9 +4,9 @@
4 4
5obj-y := \ 5obj-y := \
6 cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ 6 cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
7 interrupt.o lock.o dpmc.o irqpanic.o 7 interrupt.o lock.o irqpanic.o
8 8
9obj-$(CONFIG_CPLB_INFO) += cplbinfo.o 9obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
10obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o 10obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o
11obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o 11obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o
12obj-$(CONFIG_PM) += pm.o 12obj-$(CONFIG_PM) += pm.o dpmc.o
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S
index 7924a90d9658..9d475623b724 100644
--- a/arch/blackfin/mach-common/cacheinit.S
+++ b/arch/blackfin/mach-common/cacheinit.S
@@ -38,104 +38,37 @@
38 38
39.text 39.text
40 40
41#ifdef ANOMALY_05000125
41#if defined(CONFIG_BLKFIN_CACHE) 42#if defined(CONFIG_BLKFIN_CACHE)
42ENTRY(_bfin_icache_init) 43ENTRY(_bfin_write_IMEM_CONTROL)
43 44
44 /* Initialize Instruction CPLBS */
45
46 I0.L = (ICPLB_ADDR0 & 0xFFFF);
47 I0.H = (ICPLB_ADDR0 >> 16);
48
49 I1.L = (ICPLB_DATA0 & 0xFFFF);
50 I1.H = (ICPLB_DATA0 >> 16);
51
52 I2.L = _icplb_table;
53 I2.H = _icplb_table;
54
55 r1 = -1; /* end point comparison */
56 r3 = 15; /* max counter */
57
58/* read entries from table */
59
60.Lread_iaddr:
61 R0 = [I2++];
62 CC = R0 == R1;
63 IF CC JUMP .Lidone;
64 [I0++] = R0;
65
66.Lread_idata:
67 R2 = [I2++];
68 [I1++] = R2;
69 R3 = R3 + R1;
70 CC = R3 == R1;
71 IF !CC JUMP .Lread_iaddr;
72
73.Lidone:
74 /* Enable Instruction Cache */ 45 /* Enable Instruction Cache */
75 P0.l = (IMEM_CONTROL & 0xFFFF); 46 P0.l = (IMEM_CONTROL & 0xFFFF);
76 P0.h = (IMEM_CONTROL >> 16); 47 P0.h = (IMEM_CONTROL >> 16);
77 R1 = [P0];
78 R0 = (IMC | ENICPLB);
79 R0 = R0 | R1;
80 48
81 /* Anomaly 05000125 */ 49 /* Anomaly 05000125 */
82 CLI R2; 50 CLI R1;
83 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ 51 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
84 .align 8; 52 .align 8;
85 [P0] = R0; 53 [P0] = R0;
86 SSYNC; 54 SSYNC;
87 STI R2; 55 STI R1;
88 RTS; 56 RTS;
89 57
90ENDPROC(_bfin_icache_init) 58ENDPROC(_bfin_write_IMEM_CONTROL)
91#endif 59#endif
92 60
93#if defined(CONFIG_BLKFIN_DCACHE) 61#if defined(CONFIG_BLKFIN_DCACHE)
94ENTRY(_bfin_dcache_init) 62ENTRY(_bfin_write_DMEM_CONTROL)
95 63 CLI R1;
96 /* Initialize Data CPLBS */
97
98 I0.L = (DCPLB_ADDR0 & 0xFFFF);
99 I0.H = (DCPLB_ADDR0 >> 16);
100
101 I1.L = (DCPLB_DATA0 & 0xFFFF);
102 I1.H = (DCPLB_DATA0 >> 16);
103
104 I2.L = _dcplb_table;
105 I2.H = _dcplb_table;
106
107 R1 = -1; /* end point comparison */
108 R3 = 15; /* max counter */
109
110 /* read entries from table */
111.Lread_daddr:
112 R0 = [I2++];
113 cc = R0 == R1;
114 IF CC JUMP .Lddone;
115 [I0++] = R0;
116
117.Lread_ddata:
118 R2 = [I2++];
119 [I1++] = R2;
120 R3 = R3 + R1;
121 CC = R3 == R1;
122 IF !CC JUMP .Lread_daddr;
123.Lddone:
124 P0.L = (DMEM_CONTROL & 0xFFFF);
125 P0.H = (DMEM_CONTROL >> 16);
126 R1 = [P0];
127
128 R0 = DMEM_CNTR;
129
130 R0 = R0 | R1;
131 /* Anomaly 05000125 */
132 CLI R2;
133 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ 64 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
134 .align 8; 65 .align 8;
135 [P0] = R0; 66 [P0] = R0;
136 SSYNC; 67 SSYNC;
137 STI R2; 68 STI R1;
138 RTS; 69 RTS;
139 70
140ENDPROC(_bfin_dcache_init) 71ENDPROC(_bfin_write_DMEM_CONTROL)
72#endif
73
141#endif 74#endif
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c
index caa9623e6bd6..785ca9816971 100644
--- a/arch/blackfin/mach-common/cplbinfo.c
+++ b/arch/blackfin/mach-common/cplbinfo.c
@@ -31,11 +31,10 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
34#include <linux/uaccess.h>
34 35
35#include <asm/current.h> 36#include <asm/current.h>
36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38
39#include <asm/cplb.h> 38#include <asm/cplb.h>
40#include <asm/blackfin.h> 39#include <asm/blackfin.h>
41 40
@@ -92,8 +91,7 @@ static char *cplb_print_entry(char *buf, int type)
92 } else 91 } else
93 buf += sprintf(buf, "Data CPLB entry:\n"); 92 buf += sprintf(buf, "Data CPLB entry:\n");
94 93
95 buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\ 94 buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\n\tiCount\toCount\n");
96\tiCount\toCount\n");
97 95
98 while (*p_addr != 0xffffffff) { 96 while (*p_addr != 0xffffffff) {
99 entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data); 97 entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
@@ -144,8 +142,7 @@ static int cplbinfo_proc_output(char *buf)
144 142
145 p = buf; 143 p = buf;
146 144
147 p += sprintf(p, 145 p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
148 "------------------ CPLB Information ------------------\n\n");
149 146
150 if (bfin_read_IMEM_CONTROL() & ENICPLB) 147 if (bfin_read_IMEM_CONTROL() & ENICPLB)
151 p = cplb_print_entry(p, CPLB_I); 148 p = cplb_print_entry(p, CPLB_I);
@@ -191,9 +188,9 @@ static int __init cplbinfo_init(void)
191{ 188{
192 struct proc_dir_entry *entry; 189 struct proc_dir_entry *entry;
193 190
194 if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) { 191 entry = create_proc_entry("cplbinfo", 0, NULL);
192 if (!entry)
195 return -ENOMEM; 193 return -ENOMEM;
196 }
197 194
198 entry->read_proc = cplbinfo_read_proc; 195 entry->read_proc = cplbinfo_read_proc;
199 entry->write_proc = cplbinfo_write_proc; 196 entry->write_proc = cplbinfo_write_proc;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 40045b1386ad..d61bba98fb54 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -49,34 +49,15 @@
49 49
50 50
51#include <linux/linkage.h> 51#include <linux/linkage.h>
52#include <linux/unistd.h>
52#include <asm/blackfin.h> 53#include <asm/blackfin.h>
53#include <asm/unistd.h>
54#include <asm/errno.h> 54#include <asm/errno.h>
55#include <asm/thread_info.h> /* TIF_NEED_RESCHED */ 55#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
56#include <asm/asm-offsets.h> 56#include <asm/asm-offsets.h>
57#include <asm/trace.h>
57 58
58#include <asm/mach-common/context.S> 59#include <asm/mach-common/context.S>
59 60
60#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
61 /*
62 * TODO: this should be proper save/restore, but for now
63 * we'll just cheat and use 0x1/0x13
64 */
65# define DEBUG_START_HWTRACE \
66 P5.l = LO(TBUFCTL); \
67 P5.h = HI(TBUFCTL); \
68 R7 = 0x13; \
69 [P5] = R7;
70# define DEBUG_STOP_HWTRACE \
71 P5.l = LO(TBUFCTL); \
72 P5.h = HI(TBUFCTL); \
73 R7 = 0x01; \
74 [P5] = R7;
75#else
76# define DEBUG_START_HWTRACE
77# define DEBUG_STOP_HWTRACE
78#endif
79
80#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 61#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
81.section .l1.text 62.section .l1.text
82#else 63#else
@@ -110,25 +91,14 @@ ENTRY(_ex_icplb)
110 ASTAT = [sp++]; 91 ASTAT = [sp++];
111 SAVE_ALL_SYS 92 SAVE_ALL_SYS
112 call __cplb_hdr; 93 call __cplb_hdr;
113 DEBUG_START_HWTRACE 94 DEBUG_START_HWTRACE(p5, r7)
114 RESTORE_ALL_SYS 95 RESTORE_ALL_SYS
115 SP = RETN; 96 SP = RETN;
116 rtx; 97 rtx;
117ENDPROC(_ex_icplb) 98ENDPROC(_ex_icplb)
118 99
119ENTRY(_ex_spinlock)
120 /* Transform this into a syscall - twiddle the syscall vector. */
121 p5.l = lo(EVT15);
122 p5.h = hi(EVT15);
123 r7.l = _spinlock_bh;
124 r7.h = _spinlock_bh;
125 [p5] = r7;
126 csync;
127 /* Fall through. */
128ENDPROC(_ex_spinlock)
129
130ENTRY(_ex_syscall) 100ENTRY(_ex_syscall)
131 DEBUG_START_HWTRACE 101 DEBUG_START_HWTRACE(p5, r7)
132 (R7:6,P5:4) = [sp++]; 102 (R7:6,P5:4) = [sp++];
133 ASTAT = [sp++]; 103 ASTAT = [sp++];
134 raise 15; /* invoked by TRAP #0, for sys call */ 104 raise 15; /* invoked by TRAP #0, for sys call */
@@ -136,26 +106,6 @@ ENTRY(_ex_syscall)
136 rtx 106 rtx
137ENDPROC(_ex_syscall) 107ENDPROC(_ex_syscall)
138 108
139ENTRY(_spinlock_bh)
140 SAVE_ALL_SYS
141 /* To end up here, vector 15 was changed - so we have to change it
142 * back.
143 */
144 p0.l = lo(EVT15);
145 p0.h = hi(EVT15);
146 p1.l = _evt_system_call;
147 p1.h = _evt_system_call;
148 [p0] = p1;
149 csync;
150 r0 = [sp + PT_R0];
151 sp += -12;
152 call _sys_bfin_spinlock;
153 sp += 12;
154 [SP + PT_R0] = R0;
155 RESTORE_ALL_SYS
156 rti;
157ENDPROC(_spinlock_bh)
158
159ENTRY(_ex_soft_bp) 109ENTRY(_ex_soft_bp)
160 r7 = retx; 110 r7 = retx;
161 r7 += -2; 111 r7 += -2;
@@ -186,7 +136,7 @@ ENTRY(_ex_single_step)
186 if !cc jump _ex_trap_c; 136 if !cc jump _ex_trap_c;
187 137
188_return_from_exception: 138_return_from_exception:
189 DEBUG_START_HWTRACE 139 DEBUG_START_HWTRACE(p5, r7)
190#ifdef ANOMALY_05000257 140#ifdef ANOMALY_05000257
191 R7=LC0; 141 R7=LC0;
192 LC0=R7; 142 LC0=R7;
@@ -208,7 +158,7 @@ ENTRY(_handle_bad_cplb)
208 * need to make a CPLB exception look like a normal exception 158 * need to make a CPLB exception look like a normal exception
209 */ 159 */
210 160
211 DEBUG_START_HWTRACE 161 DEBUG_START_HWTRACE(p5, r7)
212 RESTORE_ALL_SYS 162 RESTORE_ALL_SYS
213 [--sp] = ASTAT; 163 [--sp] = ASTAT;
214 [--sp] = (R7:6, P5:4); 164 [--sp] = (R7:6, P5:4);
@@ -251,7 +201,7 @@ ENTRY(_ex_trap_c)
251 R6 = SEQSTAT; 201 R6 = SEQSTAT;
252 [P5] = R6; 202 [P5] = R6;
253 203
254 DEBUG_START_HWTRACE 204 DEBUG_START_HWTRACE(p5, r7)
255 (R7:6,P5:4) = [sp++]; 205 (R7:6,P5:4) = [sp++];
256 ASTAT = [sp++]; 206 ASTAT = [sp++];
257 SP = RETN; 207 SP = RETN;
@@ -335,7 +285,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
335 /* Try to deal with syscalls quickly. */ 285 /* Try to deal with syscalls quickly. */
336 [--sp] = ASTAT; 286 [--sp] = ASTAT;
337 [--sp] = (R7:6, P5:4); 287 [--sp] = (R7:6, P5:4);
338 DEBUG_STOP_HWTRACE 288 DEBUG_STOP_HWTRACE(p5, r7)
339 r7 = SEQSTAT; /* reason code is in bit 5:0 */ 289 r7 = SEQSTAT; /* reason code is in bit 5:0 */
340 r6.l = lo(SEQSTAT_EXCAUSE); 290 r6.l = lo(SEQSTAT_EXCAUSE);
341 r6.h = hi(SEQSTAT_EXCAUSE); 291 r6.h = hi(SEQSTAT_EXCAUSE);
@@ -741,6 +691,10 @@ _schedule_and_signal_from_int:
741 r0 = [p0]; 691 r0 = [p0];
742 sti r0; 692 sti r0;
743 693
694 r0 = sp;
695 sp += -12;
696 call _finish_atomic_sections;
697 sp += 12;
744 jump.s .Lresume_userspace; 698 jump.s .Lresume_userspace;
745 699
746_schedule_and_signal: 700_schedule_and_signal:
@@ -790,14 +744,14 @@ ENDPROC(_init_exception_buff)
790ALIGN 744ALIGN
791_extable: 745_extable:
792 /* entry for each EXCAUSE[5:0] 746 /* entry for each EXCAUSE[5:0]
793 * This table bmust be in sync with the table in ./kernel/traps.c 747 * This table must be in sync with the table in ./kernel/traps.c
794 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined 748 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
795 */ 749 */
796 .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ 750 .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */
797 .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ 751 .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
798 .long _ex_trap_c /* 0x02 - User Defined */ 752 .long _ex_trap_c /* 0x02 - User Defined */
799 .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */ 753 .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */
800 .long _ex_spinlock /* 0x04 - User Defined */ 754 .long _ex_trap_c /* 0x04 - User Defined */
801 .long _ex_trap_c /* 0x05 - User Defined */ 755 .long _ex_trap_c /* 0x05 - User Defined */
802 .long _ex_trap_c /* 0x06 - User Defined */ 756 .long _ex_trap_c /* 0x06 - User Defined */
803 .long _ex_trap_c /* 0x07 - User Defined */ 757 .long _ex_trap_c /* 0x07 - User Defined */
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 8be548e061bf..203e20709163 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -34,6 +34,7 @@
34#include <linux/linkage.h> 34#include <linux/linkage.h>
35#include <asm/entry.h> 35#include <asm/entry.h>
36#include <asm/asm-offsets.h> 36#include <asm/asm-offsets.h>
37#include <asm/trace.h>
37 38
38#include <asm/mach-common/context.S> 39#include <asm/mach-common/context.S>
39 40
@@ -170,10 +171,9 @@ ENTRY(_evt_ivhw)
170 r7.l = W[p5]; 171 r7.l = W[p5];
1711: 1721:
172#endif 173#endif
173 p0.l = lo(TBUFCTL); 174
174 p0.h = hi(TBUFCTL); 175 trace_buffer_stop(p0, r0);
175 r0 = 1; 176
176 [p0] = r0;
177 r0 = IRQ_HWERR; 177 r0 = IRQ_HWERR;
178 r1 = sp; 178 r1 = sp;
179 179
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 80943bbd37c2..6b9fd03ce835 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -183,7 +183,7 @@ static void bf561_gpio_ack_irq(unsigned int irq)
183{ 183{
184 u16 gpionr = irq - IRQ_PF0; 184 u16 gpionr = irq - IRQ_PF0;
185 185
186 if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { 186 if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
187 set_gpio_data(gpionr, 0); 187 set_gpio_data(gpionr, 0);
188 SSYNC(); 188 SSYNC();
189 } 189 }
@@ -193,7 +193,7 @@ static void bf561_gpio_mask_ack_irq(unsigned int irq)
193{ 193{
194 u16 gpionr = irq - IRQ_PF0; 194 u16 gpionr = irq - IRQ_PF0;
195 195
196 if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { 196 if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
197 set_gpio_data(gpionr, 0); 197 set_gpio_data(gpionr, 0);
198 SSYNC(); 198 SSYNC();
199 } 199 }
@@ -222,7 +222,7 @@ static unsigned int bf561_gpio_irq_startup(unsigned int irq)
222 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 222 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
223 223
224 ret = gpio_request(gpionr, NULL); 224 ret = gpio_request(gpionr, NULL);
225 if(ret) 225 if (ret)
226 return ret; 226 return ret;
227 227
228 } 228 }
@@ -262,7 +262,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
262 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 262 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
263 263
264 ret = gpio_request(gpionr, NULL); 264 ret = gpio_request(gpionr, NULL);
265 if(ret) 265 if (ret)
266 return ret; 266 return ret;
267 267
268 } 268 }
@@ -371,6 +371,9 @@ int __init init_arch_irq(void)
371 bfin_write_SICA_IMASK1(SIC_UNMASK_ALL); 371 bfin_write_SICA_IMASK1(SIC_UNMASK_ALL);
372 SSYNC(); 372 SSYNC();
373 373
374 bfin_write_SICA_IWR0(IWR_ENABLE_ALL);
375 bfin_write_SICA_IWR1(IWR_ENABLE_ALL);
376
374 local_irq_disable(); 377 local_irq_disable();
375 378
376 init_exception_buff(); 379 init_exception_buff();
@@ -393,7 +396,7 @@ int __init init_arch_irq(void)
393 bfin_write_EVT15(evt_system_call); 396 bfin_write_EVT15(evt_system_call);
394 CSYNC(); 397 CSYNC();
395 398
396 for (irq = 0; irq < SYS_IRQS; irq++) { 399 for (irq = 0; irq <= SYS_IRQS; irq++) {
397 if (irq <= IRQ_CORETMR) 400 if (irq <= IRQ_CORETMR)
398 set_irq_chip(irq, &bf561_core_irqchip); 401 set_irq_chip(irq, &bf561_core_irqchip);
399 else 402 else
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index 2cfc7d5aec5c..28a878c3577a 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -13,7 +13,7 @@
13 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> 13 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
14 * 2003 Metrowerks/Motorola 14 * 2003 Metrowerks/Motorola
15 * 2003 Bas Vermeulen <bas@buyways.nl> 15 * 2003 Bas Vermeulen <bas@buyways.nl>
16 * Copyright 2004-2006 Analog Devices Inc. 16 * Copyright 2004-2007 Analog Devices Inc.
17 * 17 *
18 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 18 * Bugs: Enter bugs at http://blackfin.uclinux.org/
19 * 19 *
@@ -65,9 +65,9 @@ atomic_t num_spurious;
65 65
66struct ivgx { 66struct ivgx {
67 /* irq number for request_irq, available in mach-bf533/irq.h */ 67 /* irq number for request_irq, available in mach-bf533/irq.h */
68 int irqno; 68 unsigned int irqno;
69 /* corresponding bit in the SIC_ISR register */ 69 /* corresponding bit in the SIC_ISR register */
70 int isrflag; 70 unsigned int isrflag;
71} ivg_table[NR_PERI_INTS]; 71} ivg_table[NR_PERI_INTS];
72 72
73struct ivg_slice { 73struct ivg_slice {
@@ -88,17 +88,16 @@ static void __init search_IAR(void)
88 for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { 88 for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
89 int irqn; 89 int irqn;
90 90
91 ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = 91 ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos];
92 &ivg_table[irq_pos];
93 92
94 for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { 93 for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
95 int iar_shift = (irqn & 7) * 4; 94 int iar_shift = (irqn & 7) * 4;
96 if (ivg == 95 if (ivg ==
97 (0xf & 96 (0xf &
98 bfin_read32((unsigned long *) SIC_IAR0 + 97 bfin_read32((unsigned long *)SIC_IAR0 +
99 (irqn >> 3)) >> iar_shift)) { 98 (irqn >> 3)) >> iar_shift)) {
100 ivg_table[irq_pos].irqno = IVG7 + irqn; 99 ivg_table[irq_pos].irqno = IVG7 + irqn;
101 ivg_table[irq_pos].isrflag = 1 << irqn; 100 ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
102 ivg7_13[ivg].istop++; 101 ivg7_13[ivg].istop++;
103 irq_pos++; 102 irq_pos++;
104 } 103 }
@@ -141,15 +140,31 @@ static void bfin_core_unmask_irq(unsigned int irq)
141 140
142static void bfin_internal_mask_irq(unsigned int irq) 141static void bfin_internal_mask_irq(unsigned int irq)
143{ 142{
143#ifndef CONFIG_BF54x
144 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & 144 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
145 ~(1 << (irq - (IRQ_CORETMR + 1)))); 145 ~(1 << (irq - (IRQ_CORETMR + 1))));
146#else
147 unsigned mask_bank, mask_bit;
148 mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
149 mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
150 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
151 ~(1 << mask_bit));
152#endif
146 SSYNC(); 153 SSYNC();
147} 154}
148 155
149static void bfin_internal_unmask_irq(unsigned int irq) 156static void bfin_internal_unmask_irq(unsigned int irq)
150{ 157{
158#ifndef CONFIG_BF54x
151 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 159 bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
152 (1 << (irq - (IRQ_CORETMR + 1)))); 160 (1 << (irq - (IRQ_CORETMR + 1))));
161#else
162 unsigned mask_bank, mask_bit;
163 mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
164 mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
165 bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
166 (1 << mask_bit));
167#endif
153 SSYNC(); 168 SSYNC();
154} 169}
155 170
@@ -206,7 +221,7 @@ static struct irq_chip bfin_generic_error_irqchip = {
206}; 221};
207 222
208static void bfin_demux_error_irq(unsigned int int_err_irq, 223static void bfin_demux_error_irq(unsigned int int_err_irq,
209 struct irq_desc *intb_desc) 224 struct irq_desc *intb_desc)
210{ 225{
211 int irq = 0; 226 int irq = 0;
212 227
@@ -270,8 +285,8 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
270 } 285 }
271 286
272 pr_debug("IRQ %d:" 287 pr_debug("IRQ %d:"
273 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", 288 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
274 irq); 289 irq);
275 } 290 }
276 } else 291 } else
277 printk(KERN_ERR 292 printk(KERN_ERR
@@ -279,11 +294,10 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
279 " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", 294 " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
280 __FUNCTION__, __FILE__, __LINE__); 295 __FUNCTION__, __FILE__, __LINE__);
281 296
282
283} 297}
284#endif /* BF537_GENERIC_ERROR_INT_DEMUX */ 298#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
285 299
286#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 300#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x)
287 301
288static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; 302static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
289static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; 303static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -361,8 +375,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
361 } 375 }
362 376
363 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | 377 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
364 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) 378 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
365 {
366 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { 379 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
367 ret = gpio_request(gpionr, NULL); 380 ret = gpio_request(gpionr, NULL);
368 if (ret) 381 if (ret)
@@ -407,7 +420,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
407 return 0; 420 return 0;
408} 421}
409 422
410
411static struct irq_chip bfin_gpio_irqchip = { 423static struct irq_chip bfin_gpio_irqchip = {
412 .ack = bfin_gpio_ack_irq, 424 .ack = bfin_gpio_ack_irq,
413 .mask = bfin_gpio_mask_irq, 425 .mask = bfin_gpio_mask_irq,
@@ -419,20 +431,20 @@ static struct irq_chip bfin_gpio_irqchip = {
419}; 431};
420 432
421static void bfin_demux_gpio_irq(unsigned int intb_irq, 433static void bfin_demux_gpio_irq(unsigned int intb_irq,
422 struct irq_desc *intb_desc) 434 struct irq_desc *intb_desc)
423{ 435{
424 u16 i; 436 u16 i;
437 struct irq_desc *desc;
425 438
426 for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) { 439 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) {
427 int irq = IRQ_PF0 + i; 440 int irq = IRQ_PF0 + i;
428 int flag_d = get_gpiop_data(i); 441 int flag_d = get_gpiop_data(i);
429 int mask = 442 int mask =
430 flag_d & (gpio_enabled[gpio_bank(i)] & 443 flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i));
431 get_gpiop_maska(i));
432 444
433 while (mask) { 445 while (mask) {
434 if (mask & 1) { 446 if (mask & 1) {
435 struct irq_desc *desc = irq_desc + irq; 447 desc = irq_desc + irq;
436 desc->handle_irq(irq, desc); 448 desc->handle_irq(irq, desc);
437 } 449 }
438 irq++; 450 irq++;
@@ -441,6 +453,264 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
441 } 453 }
442} 454}
443 455
456#else /* CONFIG_IRQCHIP_DEMUX_GPIO */
457
458#define NR_PINT_SYS_IRQS 4
459#define NR_PINT_BITS 32
460#define NR_PINTS 160
461#define IRQ_NOT_AVAIL 0xFF
462
463#define PINT_2_BANK(x) ((x) >> 5)
464#define PINT_2_BIT(x) ((x) & 0x1F)
465#define PINT_BIT(x) (1 << (PINT_2_BIT(x)))
466
467static unsigned char irq2pint_lut[NR_PINTS];
468static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
469
470struct pin_int_t {
471 unsigned int mask_set;
472 unsigned int mask_clear;
473 unsigned int request;
474 unsigned int assign;
475 unsigned int edge_set;
476 unsigned int edge_clear;
477 unsigned int invert_set;
478 unsigned int invert_clear;
479 unsigned int pinstate;
480 unsigned int latch;
481};
482
483static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
484 (struct pin_int_t *)PINT0_MASK_SET,
485 (struct pin_int_t *)PINT1_MASK_SET,
486 (struct pin_int_t *)PINT2_MASK_SET,
487 (struct pin_int_t *)PINT3_MASK_SET,
488};
489
490unsigned short get_irq_base(u8 bank, u8 bmap)
491{
492
493 u16 irq_base;
494
495 if (bank < 2) { /*PA-PB */
496 irq_base = IRQ_PA0 + bmap * 16;
497 } else { /*PC-PJ */
498 irq_base = IRQ_PC0 + bmap * 16;
499 }
500
501 return irq_base;
502
503}
504
505 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
506void init_pint_lut(void)
507{
508 u16 bank, bit, irq_base, bit_pos;
509 u32 pint_assign;
510 u8 bmap;
511
512 memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut));
513
514 for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
515
516 pint_assign = pint[bank]->assign;
517
518 for (bit = 0; bit < NR_PINT_BITS; bit++) {
519
520 bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF;
521
522 irq_base = get_irq_base(bank, bmap);
523
524 irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0);
525 bit_pos = bit + bank * NR_PINT_BITS;
526
527 pint2irq_lut[bit_pos] = irq_base - SYS_IRQS;
528 irq2pint_lut[irq_base - SYS_IRQS] = bit_pos;
529
530 }
531
532 }
533
534}
535
536static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
537
538static void bfin_gpio_ack_irq(unsigned int irq)
539{
540 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
541
542 pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
543 SSYNC();
544}
545
546static void bfin_gpio_mask_ack_irq(unsigned int irq)
547{
548 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
549 u32 pintbit = PINT_BIT(pint_val);
550 u8 bank = PINT_2_BANK(pint_val);
551
552 pint[bank]->request = pintbit;
553 pint[bank]->mask_clear = pintbit;
554 SSYNC();
555}
556
557static void bfin_gpio_mask_irq(unsigned int irq)
558{
559 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
560
561 pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
562 SSYNC();
563}
564
565static void bfin_gpio_unmask_irq(unsigned int irq)
566{
567 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
568 u32 pintbit = PINT_BIT(pint_val);
569 u8 bank = PINT_2_BANK(pint_val);
570
571 pint[bank]->request = pintbit;
572 pint[bank]->mask_set = pintbit;
573 SSYNC();
574}
575
576static unsigned int bfin_gpio_irq_startup(unsigned int irq)
577{
578 unsigned int ret;
579 u16 gpionr = irq - IRQ_PA0;
580 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
581
582 if (pint_val == IRQ_NOT_AVAIL)
583 return -ENODEV;
584
585 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
586 ret = gpio_request(gpionr, NULL);
587 if (ret)
588 return ret;
589 }
590
591 gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
592 bfin_gpio_unmask_irq(irq);
593
594 return ret;
595}
596
597static void bfin_gpio_irq_shutdown(unsigned int irq)
598{
599 bfin_gpio_mask_irq(irq);
600 gpio_free(irq - IRQ_PA0);
601 gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
602}
603
604static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
605{
606
607 unsigned int ret;
608 u16 gpionr = irq - IRQ_PA0;
609 u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
610 u32 pintbit = PINT_BIT(pint_val);
611 u8 bank = PINT_2_BANK(pint_val);
612
613 if (pint_val == IRQ_NOT_AVAIL)
614 return -ENODEV;
615
616 if (type == IRQ_TYPE_PROBE) {
617 /* only probe unenabled GPIO interrupt lines */
618 if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
619 return 0;
620 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
621 }
622
623 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
624 IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
625 if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
626 ret = gpio_request(gpionr, NULL);
627 if (ret)
628 return ret;
629 }
630
631 gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
632 } else {
633 gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
634 return 0;
635 }
636
637 gpio_direction_input(gpionr);
638
639 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
640 pint[bank]->edge_set = pintbit;
641 } else {
642 pint[bank]->edge_clear = pintbit;
643 }
644
645 if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
646 pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */
647 else
648 pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */
649
650 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
651 pint[bank]->invert_set = pintbit;
652 else
653 pint[bank]->invert_set = pintbit;
654
655 SSYNC();
656
657 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
658 set_irq_handler(irq, handle_edge_irq);
659 else
660 set_irq_handler(irq, handle_level_irq);
661
662 return 0;
663}
664
665static struct irq_chip bfin_gpio_irqchip = {
666 .ack = bfin_gpio_ack_irq,
667 .mask = bfin_gpio_mask_irq,
668 .mask_ack = bfin_gpio_mask_ack_irq,
669 .unmask = bfin_gpio_unmask_irq,
670 .set_type = bfin_gpio_irq_type,
671 .startup = bfin_gpio_irq_startup,
672 .shutdown = bfin_gpio_irq_shutdown
673};
674
675static void bfin_demux_gpio_irq(unsigned int intb_irq,
676 struct irq_desc *intb_desc)
677{
678 u8 bank, pint_val;
679 u32 request, irq;
680 struct irq_desc *desc;
681
682 switch (intb_irq) {
683 case IRQ_PINT0:
684 bank = 0;
685 break;
686 case IRQ_PINT2:
687 bank = 2;
688 break;
689 case IRQ_PINT3:
690 bank = 3;
691 break;
692 case IRQ_PINT1:
693 bank = 1;
694 break;
695 default:
696 return;
697 }
698
699 pint_val = bank * NR_PINT_BITS;
700
701 request = pint[bank]->request;
702
703 while (request) {
704 if (request & 1) {
705 irq = pint2irq_lut[pint_val] + SYS_IRQS;
706 desc = irq_desc + irq;
707 desc->handle_irq(irq, desc);
708 }
709 pint_val++;
710 request >>= 1;
711 }
712
713}
444#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ 714#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
445 715
446/* 716/*
@@ -452,7 +722,18 @@ int __init init_arch_irq(void)
452 int irq; 722 int irq;
453 unsigned long ilat = 0; 723 unsigned long ilat = 0;
454 /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ 724 /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
725#ifdef CONFIG_BF54x
726 bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
727 bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
728 bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
729 bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
730 bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
731 bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
732#else
455 bfin_write_SIC_IMASK(SIC_UNMASK_ALL); 733 bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
734 bfin_write_SIC_IWR(IWR_ENABLE_ALL);
735#endif
736
456 SSYNC(); 737 SSYNC();
457 738
458 local_irq_disable(); 739 local_irq_disable();
@@ -475,7 +756,18 @@ int __init init_arch_irq(void)
475 bfin_write_EVT15(evt_system_call); 756 bfin_write_EVT15(evt_system_call);
476 CSYNC(); 757 CSYNC();
477 758
478 for (irq = 0; irq < SYS_IRQS; irq++) { 759#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x)
760#ifdef CONFIG_PINTx_REASSIGN
761 pint[0]->assign = CONFIG_PINT0_ASSIGN;
762 pint[1]->assign = CONFIG_PINT1_ASSIGN;
763 pint[2]->assign = CONFIG_PINT2_ASSIGN;
764 pint[3]->assign = CONFIG_PINT3_ASSIGN;
765#endif
766 /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
767 init_pint_lut();
768#endif
769
770 for (irq = 0; irq <= SYS_IRQS; irq++) {
479 if (irq <= IRQ_CORETMR) 771 if (irq <= IRQ_CORETMR)
480 set_irq_chip(irq, &bfin_core_irqchip); 772 set_irq_chip(irq, &bfin_core_irqchip);
481 else 773 else
@@ -484,20 +776,42 @@ int __init init_arch_irq(void)
484 if (irq != IRQ_GENERIC_ERROR) { 776 if (irq != IRQ_GENERIC_ERROR) {
485#endif 777#endif
486 778
779 switch (irq) {
487#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 780#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
488 if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ 781#ifndef CONFIG_BF54x
489# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) 782 case IRQ_PROG_INTA:
490 && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ 783 set_irq_chained_handler(irq,
491# endif 784 bfin_demux_gpio_irq);
492 ) { 785 break;
786#if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
787 case IRQ_MAC_RX:
788 set_irq_chained_handler(irq,
789 bfin_demux_gpio_irq);
790 break;
493#endif 791#endif
494 set_irq_handler(irq, handle_simple_irq); 792#else
495#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 793 case IRQ_PINT0:
496 } else {
497 set_irq_chained_handler(irq, 794 set_irq_chained_handler(irq,
498 bfin_demux_gpio_irq); 795 bfin_demux_gpio_irq);
499 } 796 break;
797 case IRQ_PINT1:
798 set_irq_chained_handler(irq,
799 bfin_demux_gpio_irq);
800 break;
801 case IRQ_PINT2:
802 set_irq_chained_handler(irq,
803 bfin_demux_gpio_irq);
804 break;
805 case IRQ_PINT3:
806 set_irq_chained_handler(irq,
807 bfin_demux_gpio_irq);
808 break;
809#endif /*CONFIG_BF54x */
500#endif 810#endif
811 default:
812 set_irq_handler(irq, handle_simple_irq);
813 break;
814 }
501 815
502#ifdef BF537_GENERIC_ERROR_INT_DEMUX 816#ifdef BF537_GENERIC_ERROR_INT_DEMUX
503 } else { 817 } else {
@@ -513,7 +827,11 @@ int __init init_arch_irq(void)
513#endif 827#endif
514 828
515#ifdef CONFIG_IRQCHIP_DEMUX_GPIO 829#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
830#ifndef CONFIG_BF54x
516 for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { 831 for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
832#else
833 for (irq = IRQ_PA0; irq < NR_IRQS; irq++) {
834#endif
517 set_irq_chip(irq, &bfin_gpio_irqchip); 835 set_irq_chip(irq, &bfin_gpio_irqchip);
518 /* if configured as edge, then will be changed to do_edge_IRQ */ 836 /* if configured as edge, then will be changed to do_edge_IRQ */
519 set_irq_handler(irq, handle_level_irq); 837 set_irq_handler(irq, handle_level_irq);
@@ -526,8 +844,7 @@ int __init init_arch_irq(void)
526 bfin_write_ILAT(ilat); 844 bfin_write_ILAT(ilat);
527 CSYNC(); 845 CSYNC();
528 846
529 printk(KERN_INFO 847 printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
530 "Configuring Blackfin Priority Driven Interrupts\n");
531 /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, 848 /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
532 * local_irq_enable() 849 * local_irq_enable()
533 */ 850 */
@@ -538,14 +855,13 @@ int __init init_arch_irq(void)
538 /* Enable interrupts IVG7-15 */ 855 /* Enable interrupts IVG7-15 */
539 irq_flags = irq_flags | IMASK_IVG15 | 856 irq_flags = irq_flags | IMASK_IVG15 |
540 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | 857 IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
541 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | 858 IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
542 IMASK_IVGHW;
543 859
544 return 0; 860 return 0;
545} 861}
546 862
547#ifdef CONFIG_DO_IRQ_L1 863#ifdef CONFIG_DO_IRQ_L1
548void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); 864void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text));
549#endif 865#endif
550 866
551void do_irq(int vec, struct pt_regs *fp) 867void do_irq(int vec, struct pt_regs *fp)
@@ -555,9 +871,25 @@ void do_irq(int vec, struct pt_regs *fp)
555 } else { 871 } else {
556 struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; 872 struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
557 struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; 873 struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
558 unsigned long sic_status; 874#ifdef CONFIG_BF54x
875 unsigned long sic_status[3];
559 876
560 SSYNC(); 877 SSYNC();
878 sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
879 sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
880 sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
881
882 for (;; ivg++) {
883 if (ivg >= ivg_stop) {
884 atomic_inc(&num_spurious);
885 return;
886 }
887 if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
888 break;
889 }
890#else
891 unsigned long sic_status;
892 SSYNC();
561 sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); 893 sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
562 894
563 for (;; ivg++) { 895 for (;; ivg++) {
@@ -567,6 +899,7 @@ void do_irq(int vec, struct pt_regs *fp)
567 } else if (sic_status & ivg->isrflag) 899 } else if (sic_status & ivg->isrflag)
568 break; 900 break;
569 } 901 }
902#endif
570 vec = ivg->irqno; 903 vec = ivg->irqno;
571 } 904 }
572 asm_do_IRQ(vec, fp); 905 asm_do_IRQ(vec, fp);
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 150ef5d088dc..1772d8d2c1a7 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -35,10 +35,10 @@
35#include <linux/pm.h> 35#include <linux/pm.h>
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/io.h>
39#include <linux/irq.h>
38 40
39#include <asm/io.h>
40#include <asm/dpmc.h> 41#include <asm/dpmc.h>
41#include <asm/irq.h>
42#include <asm/gpio.h> 42#include <asm/gpio.h>
43 43
44#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H 44#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H
diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c
index 68107924639e..16c6169ed01b 100644
--- a/arch/blackfin/mm/blackfin_sram.c
+++ b/arch/blackfin/mm/blackfin_sram.c
@@ -87,7 +87,7 @@ void __init l1sram_init(void)
87 L1_SCRATCH_LENGTH >> 10); 87 L1_SCRATCH_LENGTH >> 10);
88 88
89 memset(&l1_ssram, 0x00, sizeof(l1_ssram)); 89 memset(&l1_ssram, 0x00, sizeof(l1_ssram));
90 l1_ssram[0].paddr = (void*)L1_SCRATCH_START; 90 l1_ssram[0].paddr = (void *)L1_SCRATCH_START;
91 l1_ssram[0].size = L1_SCRATCH_LENGTH; 91 l1_ssram[0].size = L1_SCRATCH_LENGTH;
92 l1_ssram[0].flag = SRAM_SLT_FREE; 92 l1_ssram[0].flag = SRAM_SLT_FREE;
93 93
@@ -126,7 +126,7 @@ void __init l1_inst_sram_init(void)
126{ 126{
127#if L1_CODE_LENGTH != 0 127#if L1_CODE_LENGTH != 0
128 memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); 128 memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram));
129 l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1); 129 l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1);
130 l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); 130 l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
131 l1_inst_sram[0].flag = SRAM_SLT_FREE; 131 l1_inst_sram[0].flag = SRAM_SLT_FREE;
132 132
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index 570356dbe028..68459cc052a1 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -29,8 +29,8 @@
29 29
30#include <linux/swap.h> 30#include <linux/swap.h>
31#include <linux/bootmem.h> 31#include <linux/bootmem.h>
32#include <linux/uaccess.h>
32#include <asm/bfin-global.h> 33#include <asm/bfin-global.h>
33#include <asm/uaccess.h>
34#include <asm/l1layout.h> 34#include <asm/l1layout.h>
35#include "blackfin_sram.h" 35#include "blackfin_sram.h"
36 36
@@ -168,42 +168,31 @@ void __init mem_init(void)
168 } 168 }
169} 169}
170 170
171#ifdef CONFIG_BLK_DEV_INITRD 171static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end)
172void __init free_initrd_mem(unsigned long start, unsigned long end)
173{ 172{
174 int pages = 0; 173 unsigned long addr;
175 for (; start < end; start += PAGE_SIZE) { 174 /* next to check that the page we free is not a partial page */
176 ClearPageReserved(virt_to_page(start)); 175 for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
177 init_page_count(virt_to_page(start)); 176 ClearPageReserved(virt_to_page(addr));
178 free_page(start); 177 init_page_count(virt_to_page(addr));
178 free_page(addr);
179 totalram_pages++; 179 totalram_pages++;
180 pages++;
181 } 180 }
182 printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); 181 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
182}
183
184#ifdef CONFIG_BLK_DEV_INITRD
185void __init free_initrd_mem(unsigned long start, unsigned long end)
186{
187 free_init_pages("initrd memory", start, end);
183} 188}
184#endif 189#endif
185 190
186void __init free_initmem(void) 191void __init free_initmem(void)
187{ 192{
188#ifdef CONFIG_RAMKERNEL 193#ifdef CONFIG_RAMKERNEL
189 unsigned long addr; 194 free_init_pages("unused kernel memory",
190 /* 195 (unsigned long)(&__init_begin),
191 * the following code should be cool even if these sections 196 (unsigned long)(&__init_end));
192 * are not page aligned.
193 */
194 addr = PAGE_ALIGN((unsigned long)(__init_begin));
195 /* next to check that the page we free is not a partial page */
196 for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
197 addr += PAGE_SIZE) {
198 ClearPageReserved(virt_to_page(addr));
199 init_page_count(virt_to_page(addr));
200 free_page(addr);
201 totalram_pages++;
202 }
203 printk(KERN_NOTICE
204 "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
205 (addr - PAGE_ALIGN((long)__init_begin)) >> 10,
206 (int)(PAGE_ALIGN((unsigned long)(__init_begin))),
207 (int)(addr - PAGE_SIZE));
208#endif 197#endif
209} 198}
diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c
index 009a1700c854..cb8b8d5af34f 100644
--- a/arch/blackfin/oprofile/common.c
+++ b/arch/blackfin/oprofile/common.c
@@ -33,12 +33,12 @@
33#include <linux/smp.h> 33#include <linux/smp.h>
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36#include <linux/ptrace.h>
37#include <linux/irq.h>
38#include <linux/io.h>
36 39
37#include <asm/ptrace.h>
38#include <asm/system.h> 40#include <asm/system.h>
39#include <asm/blackfin.h> 41#include <asm/blackfin.h>
40#include <asm/irq.h>
41#include <asm/io.h>
42 42
43#include "op_blackfin.h" 43#include "op_blackfin.h"
44 44
diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c
index b7a20a006b49..872dffe33623 100644
--- a/arch/blackfin/oprofile/op_model_bf533.c
+++ b/arch/blackfin/oprofile/op_model_bf533.c
@@ -32,12 +32,12 @@
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/smp.h> 33#include <linux/smp.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <asm/ptrace.h> 35#include <linux/ptrace.h>
36#include <linux/irq.h>
37#include <linux/io.h>
36#include <asm/system.h> 38#include <asm/system.h>
37#include <asm/processor.h> 39#include <asm/processor.h>
38#include <asm/blackfin.h> 40#include <asm/blackfin.h>
39#include <asm/irq.h>
40#include <asm/io.h>
41 41
42#include "op_blackfin.h" 42#include "op_blackfin.h"
43 43
diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c
index 8fba16c846c9..6c6f8606af4c 100644
--- a/arch/blackfin/oprofile/timer_int.c
+++ b/arch/blackfin/oprofile/timer_int.c
@@ -31,8 +31,7 @@
31#include <linux/smp.h> 31#include <linux/smp.h>
32#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/oprofile.h> 33#include <linux/oprofile.h>
34 34#include <linux/ptrace.h>
35#include <asm/ptrace.h>
36 35
37static void enable_sys_timer0() 36static void enable_sys_timer0()
38{ 37{
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 5c95ceb7f122..9cbe76c3aa35 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -344,8 +344,8 @@ config X86_CMOV
344 depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) 344 depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
345 default y 345 default y
346 346
347config X86_MINIMUM_CPU_MODEL 347config X86_MINIMUM_CPU_FAMILY
348 int 348 int
349 default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP 349 default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
350 default "0" 350 default "3"
351 351
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index bfbc32098a4a..08678a0a3d19 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -25,27 +25,56 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
25 25
26#RAMDISK := -DRAMDISK=512 26#RAMDISK := -DRAMDISK=512
27 27
28targets := vmlinux.bin bootsect bootsect.o \ 28targets := vmlinux.bin setup.bin setup.elf zImage bzImage
29 setup setup.o zImage bzImage
30subdir- := compressed 29subdir- := compressed
31 30
31setup-y += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
32setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
33setup-y += printf.o string.o tty.o video.o version.o voyager.o
34
35# The link order of the video-*.o modules can matter. In particular,
36# video-vga.o *must* be listed first, followed by video-vesa.o.
37# Hardware-specific drivers should follow in the order they should be
38# probed, and video-bios.o should typically be last.
39setup-y += video-vga.o
40setup-y += video-vesa.o
41setup-y += video-bios.o
42
32hostprogs-y := tools/build 43hostprogs-y := tools/build
33 44
34HOSTCFLAGS_build.o := $(LINUXINCLUDE) 45HOSTCFLAGS_build.o := $(LINUXINCLUDE)
35 46
36# --------------------------------------------------------------------------- 47# ---------------------------------------------------------------------------
37 48
49# How to compile the 16-bit code. Note we always compile for -march=i386,
50# that way we can complain to the user if the CPU is insufficient.
51cflags-i386 :=
52cflags-x86_64 := -m32
53CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
54 $(cflags-$(ARCH)) \
55 -Wall -Wstrict-prototypes \
56 -march=i386 -mregparm=3 \
57 -include $(srctree)/$(src)/code16gcc.h \
58 -fno-strict-aliasing -fomit-frame-pointer \
59 $(call cc-option, -ffreestanding) \
60 $(call cc-option, -fno-toplevel-reorder,\
61 $(call cc-option, -fno-unit-at-a-time)) \
62 $(call cc-option, -fno-stack-protector) \
63 $(call cc-option, -mpreferred-stack-boundary=2)
64AFLAGS := $(CFLAGS) -D__ASSEMBLY__
65
38$(obj)/zImage: IMAGE_OFFSET := 0x1000 66$(obj)/zImage: IMAGE_OFFSET := 0x1000
39$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) 67$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
40$(obj)/bzImage: IMAGE_OFFSET := 0x100000 68$(obj)/bzImage: IMAGE_OFFSET := 0x100000
69$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
41$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ 70$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
42$(obj)/bzImage: BUILDFLAGS := -b 71$(obj)/bzImage: BUILDFLAGS := -b
43 72
44quiet_cmd_image = BUILD $@ 73quiet_cmd_image = BUILD $@
45cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ 74cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
46 $(obj)/vmlinux.bin $(ROOT_DEV) > $@ 75 $(obj)/vmlinux.bin $(ROOT_DEV) > $@
47 76
48$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ 77$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
49 $(obj)/vmlinux.bin $(obj)/tools/build FORCE 78 $(obj)/vmlinux.bin $(obj)/tools/build FORCE
50 $(call if_changed,image) 79 $(call if_changed,image)
51 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' 80 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -53,12 +82,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
53$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE 82$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
54 $(call if_changed,objcopy) 83 $(call if_changed,objcopy)
55 84
56LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary 85SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
57LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
58 86
59$(obj)/setup $(obj)/bootsect: %: %.o FORCE 87LDFLAGS_setup.elf := -T
88$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
60 $(call if_changed,ld) 89 $(call if_changed,ld)
61 90
91OBJCOPYFLAGS_setup.bin := -O binary
92
93$(obj)/setup.bin: $(obj)/setup.elf FORCE
94 $(call if_changed,objcopy)
95
62$(obj)/compressed/vmlinux: FORCE 96$(obj)/compressed/vmlinux: FORCE
63 $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ 97 $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
64 98
diff --git a/arch/i386/boot/a20.c b/arch/i386/boot/a20.c
new file mode 100644
index 000000000000..31348d054fca
--- /dev/null
+++ b/arch/i386/boot/a20.c
@@ -0,0 +1,161 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/a20.c
13 *
14 * Enable A20 gate (return -1 on failure)
15 */
16
17#include "boot.h"
18
19#define MAX_8042_LOOPS 100000
20
21static int empty_8042(void)
22{
23 u8 status;
24 int loops = MAX_8042_LOOPS;
25
26 while (loops--) {
27 io_delay();
28
29 status = inb(0x64);
30 if (status & 1) {
31 /* Read and discard input data */
32 io_delay();
33 (void)inb(0x60);
34 } else if (!(status & 2)) {
35 /* Buffers empty, finished! */
36 return 0;
37 }
38 }
39
40 return -1;
41}
42
43/* Returns nonzero if the A20 line is enabled. The memory address
44 used as a test is the int $0x80 vector, which should be safe. */
45
46#define A20_TEST_ADDR (4*0x80)
47#define A20_TEST_SHORT 32
48#define A20_TEST_LONG 2097152 /* 2^21 */
49
50static int a20_test(int loops)
51{
52 int ok = 0;
53 int saved, ctr;
54
55 set_fs(0x0000);
56 set_gs(0xffff);
57
58 saved = ctr = rdfs32(A20_TEST_ADDR);
59
60 while (loops--) {
61 wrfs32(++ctr, A20_TEST_ADDR);
62 io_delay(); /* Serialize and make delay constant */
63 ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
64 if (ok)
65 break;
66 }
67
68 wrfs32(saved, A20_TEST_ADDR);
69 return ok;
70}
71
72/* Quick test to see if A20 is already enabled */
73static int a20_test_short(void)
74{
75 return a20_test(A20_TEST_SHORT);
76}
77
78/* Longer test that actually waits for A20 to come on line; this
79 is useful when dealing with the KBC or other slow external circuitry. */
80static int a20_test_long(void)
81{
82 return a20_test(A20_TEST_LONG);
83}
84
85static void enable_a20_bios(void)
86{
87 asm volatile("pushfl; int $0x15; popfl"
88 : : "a" ((u16)0x2401));
89}
90
91static void enable_a20_kbc(void)
92{
93 empty_8042();
94
95 outb(0xd1, 0x64); /* Command write */
96 empty_8042();
97
98 outb(0xdf, 0x60); /* A20 on */
99 empty_8042();
100}
101
102static void enable_a20_fast(void)
103{
104 u8 port_a;
105
106 port_a = inb(0x92); /* Configuration port A */
107 port_a |= 0x02; /* Enable A20 */
108 port_a &= ~0x01; /* Do not reset machine */
109 outb(port_a, 0x92);
110}
111
112/*
113 * Actual routine to enable A20; return 0 on ok, -1 on failure
114 */
115
116#define A20_ENABLE_LOOPS 255 /* Number of times to try */
117
118int enable_a20(void)
119{
120 int loops = A20_ENABLE_LOOPS;
121
122#if defined(CONFIG_X86_ELAN)
123 /* Elan croaks if we try to touch the KBC */
124 enable_a20_fast();
125 while (!a20_test_long())
126 ;
127 return 0;
128#elif defined(CONFIG_X86_VOYAGER)
129 /* On Voyager, a20_test() is unsafe? */
130 enable_a20_kbc();
131 return 0;
132#else
133 while (loops--) {
134 /* First, check to see if A20 is already enabled
135 (legacy free, etc.) */
136 if (a20_test_short())
137 return 0;
138
139 /* Next, try the BIOS (INT 0x15, AX=0x2401) */
140 enable_a20_bios();
141 if (a20_test_short())
142 return 0;
143
144 /* Try enabling A20 through the keyboard controller */
145 empty_8042();
146 if (a20_test_short())
147 return 0; /* BIOS worked, but with delayed reaction */
148
149 enable_a20_kbc();
150 if (a20_test_long())
151 return 0;
152
153 /* Finally, try enabling the "fast A20 gate" */
154 enable_a20_fast();
155 if (a20_test_long())
156 return 0;
157 }
158
159 return -1;
160#endif
161}
diff --git a/arch/i386/boot/apm.c b/arch/i386/boot/apm.c
new file mode 100644
index 000000000000..a34087c370c0
--- /dev/null
+++ b/arch/i386/boot/apm.c
@@ -0,0 +1,97 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * Original APM BIOS checking by Stephen Rothwell, May 1994
7 * (sfr@canb.auug.org.au)
8 *
9 * This file is part of the Linux kernel, and is made available under
10 * the terms of the GNU General Public License version 2.
11 *
12 * ----------------------------------------------------------------------- */
13
14/*
15 * arch/i386/boot/apm.c
16 *
17 * Get APM BIOS information
18 */
19
20#include "boot.h"
21
22#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
23
24int query_apm_bios(void)
25{
26 u16 ax, bx, cx, dx, di;
27 u32 ebx, esi;
28 u8 err;
29
30 /* APM BIOS installation check */
31 ax = 0x5300;
32 bx = cx = 0;
33 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
34 : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
35 : : "esi", "edi");
36
37 if (err)
38 return -1; /* No APM BIOS */
39
40 if (bx != 0x504d) /* "PM" signature */
41 return -1;
42
43 if (cx & 0x02) /* 32 bits supported? */
44 return -1;
45
46 /* Disconnect first, just in case */
47 ax = 0x5304;
48 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
49 : "+a" (ax)
50 : : "ebx", "ecx", "edx", "esi", "edi");
51
52 /* Paranoia */
53 ebx = esi = 0;
54 cx = dx = di = 0;
55
56 /* 32-bit connect */
57 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
58 : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
59 "+S" (esi), "+D" (di), "=m" (err)
60 : "a" (0x5303));
61
62 boot_params.apm_bios_info.cseg = ax;
63 boot_params.apm_bios_info.offset = ebx;
64 boot_params.apm_bios_info.cseg_16 = cx;
65 boot_params.apm_bios_info.dseg = dx;
66 boot_params.apm_bios_info.cseg_len = (u16)esi;
67 boot_params.apm_bios_info.cseg_16_len = esi >> 16;
68 boot_params.apm_bios_info.dseg_len = di;
69
70 if (err)
71 return -1;
72
73 /* Redo the installation check as the 32-bit connect;
74 some BIOSes return different flags this way... */
75
76 ax = 0x5300;
77 bx = cx = 0;
78 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
79 : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
80 : : "esi", "edi");
81
82 if (err || bx != 0x504d) {
83 /* Failure with 32-bit connect, try to disconect and ignore */
84 ax = 0x5304;
85 bx = 0;
86 asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
87 : "+a" (ax), "+b" (bx)
88 : : "ecx", "edx", "esi", "edi");
89 return -1;
90 }
91
92 boot_params.apm_bios_info.version = ax;
93 boot_params.apm_bios_info.flags = cx;
94 return 0;
95}
96
97#endif
diff --git a/arch/i386/boot/bitops.h b/arch/i386/boot/bitops.h
new file mode 100644
index 000000000000..8dcc8dc7db88
--- /dev/null
+++ b/arch/i386/boot/bitops.h
@@ -0,0 +1,45 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/bitops.h
13 *
14 * Very simple bitops for the boot code.
15 */
16
17#ifndef BOOT_BITOPS_H
18#define BOOT_BITOPS_H
19#define _LINUX_BITOPS_H /* Inhibit inclusion of <linux/bitops.h> */
20
21static inline int constant_test_bit(int nr, const void *addr)
22{
23 const u32 *p = (const u32 *)addr;
24 return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
25}
26static inline int variable_test_bit(int nr, const void *addr)
27{
28 u8 v;
29 const u32 *p = (const u32 *)addr;
30
31 asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
32 return v;
33}
34
35#define test_bit(nr,addr) \
36(__builtin_constant_p(nr) ? \
37 constant_test_bit((nr),(addr)) : \
38 variable_test_bit((nr),(addr)))
39
40static inline void set_bit(int nr, void *addr)
41{
42 asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
43}
44
45#endif /* BOOT_BITOPS_H */
diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h
new file mode 100644
index 000000000000..0329c4fe4f88
--- /dev/null
+++ b/arch/i386/boot/boot.h
@@ -0,0 +1,296 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/boot.h
13 *
14 * Header file for the real-mode kernel code
15 */
16
17#ifndef BOOT_BOOT_H
18#define BOOT_BOOT_H
19
20#ifndef __ASSEMBLY__
21
22#include <stdarg.h>
23#include <linux/types.h>
24#include <linux/edd.h>
25#include <asm/boot.h>
26#include <asm/bootparam.h>
27
28/* Useful macros */
29#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
30
31extern struct setup_header hdr;
32extern struct boot_params boot_params;
33
34/* Basic port I/O */
35static inline void outb(u8 v, u16 port)
36{
37 asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
38}
39static inline u8 inb(u16 port)
40{
41 u8 v;
42 asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
43 return v;
44}
45
46static inline void outw(u16 v, u16 port)
47{
48 asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
49}
50static inline u16 inw(u16 port)
51{
52 u16 v;
53 asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
54 return v;
55}
56
57static inline void outl(u32 v, u16 port)
58{
59 asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
60}
61static inline u32 inl(u32 port)
62{
63 u32 v;
64 asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
65 return v;
66}
67
68static inline void io_delay(void)
69{
70 const u16 DELAY_PORT = 0x80;
71 asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
72}
73
74/* These functions are used to reference data in other segments. */
75
76static inline u16 ds(void)
77{
78 u16 seg;
79 asm("movw %%ds,%0" : "=rm" (seg));
80 return seg;
81}
82
83static inline void set_fs(u16 seg)
84{
85 asm volatile("movw %0,%%fs" : : "rm" (seg));
86}
87static inline u16 fs(void)
88{
89 u16 seg;
90 asm("movw %%fs,%0" : "=rm" (seg));
91 return seg;
92}
93
94static inline void set_gs(u16 seg)
95{
96 asm volatile("movw %0,%%gs" : : "rm" (seg));
97}
98static inline u16 gs(void)
99{
100 u16 seg;
101 asm("movw %%gs,%0" : "=rm" (seg));
102 return seg;
103}
104
105typedef unsigned int addr_t;
106
107static inline u8 rdfs8(addr_t addr)
108{
109 u8 v;
110 asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
111 return v;
112}
113static inline u16 rdfs16(addr_t addr)
114{
115 u16 v;
116 asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
117 return v;
118}
119static inline u32 rdfs32(addr_t addr)
120{
121 u32 v;
122 asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
123 return v;
124}
125
126static inline void wrfs8(u8 v, addr_t addr)
127{
128 asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
129}
130static inline void wrfs16(u16 v, addr_t addr)
131{
132 asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
133}
134static inline void wrfs32(u32 v, addr_t addr)
135{
136 asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
137}
138
139static inline u8 rdgs8(addr_t addr)
140{
141 u8 v;
142 asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
143 return v;
144}
145static inline u16 rdgs16(addr_t addr)
146{
147 u16 v;
148 asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
149 return v;
150}
151static inline u32 rdgs32(addr_t addr)
152{
153 u32 v;
154 asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
155 return v;
156}
157
158static inline void wrgs8(u8 v, addr_t addr)
159{
160 asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
161}
162static inline void wrgs16(u16 v, addr_t addr)
163{
164 asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
165}
166static inline void wrgs32(u32 v, addr_t addr)
167{
168 asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
169}
170
171/* Note: these only return true/false, not a signed return value! */
172static inline int memcmp(const void *s1, const void *s2, size_t len)
173{
174 u8 diff;
175 asm("repe; cmpsb; setnz %0"
176 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
177 return diff;
178}
179
180static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
181{
182 u8 diff;
183 asm("fs; repe; cmpsb; setnz %0"
184 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
185 return diff;
186}
187static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
188{
189 u8 diff;
190 asm("gs; repe; cmpsb; setnz %0"
191 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
192 return diff;
193}
194
195static inline int isdigit(int ch)
196{
197 return (ch >= '0') && (ch <= '9');
198}
199
200/* Heap -- available for dynamic lists. */
201#define STACK_SIZE 512 /* Minimum number of bytes for stack */
202
203extern char _end[];
204extern char *HEAP;
205extern char *heap_end;
206#define RESET_HEAP() ((void *)( HEAP = _end ))
207static inline char *__get_heap(size_t s, size_t a, size_t n)
208{
209 char *tmp;
210
211 HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
212 tmp = HEAP;
213 HEAP += s*n;
214 return tmp;
215}
216#define GET_HEAP(type, n) \
217 ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
218
219static inline int heap_free(void)
220{
221 return heap_end-HEAP;
222}
223
224/* copy.S */
225
226void copy_to_fs(addr_t dst, void *src, size_t len);
227void *copy_from_fs(void *dst, addr_t src, size_t len);
228void copy_to_gs(addr_t dst, void *src, size_t len);
229void *copy_from_gs(void *dst, addr_t src, size_t len);
230void *memcpy(void *dst, void *src, size_t len);
231void *memset(void *dst, int c, size_t len);
232
233#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
234#define memset(d,c,l) __builtin_memset(d,c,l)
235
236/* a20.c */
237int enable_a20(void);
238
239/* apm.c */
240int query_apm_bios(void);
241
242/* cmdline.c */
243int cmdline_find_option(const char *option, char *buffer, int bufsize);
244
245/* cpu.c, cpucheck.c */
246int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
247int validate_cpu(void);
248
249/* edd.c */
250void query_edd(void);
251
252/* header.S */
253void __attribute__((noreturn)) die(void);
254
255/* mca.c */
256int query_mca(void);
257
258/* memory.c */
259int detect_memory(void);
260
261/* pm.c */
262void __attribute__((noreturn)) go_to_protected_mode(void);
263
264/* pmjump.S */
265void __attribute__((noreturn))
266 protected_mode_jump(u32 entrypoint, u32 bootparams);
267
268/* printf.c */
269int sprintf(char *buf, const char *fmt, ...);
270int vsprintf(char *buf, const char *fmt, va_list args);
271int printf(const char *fmt, ...);
272
273/* string.c */
274int strcmp(const char *str1, const char *str2);
275size_t strnlen(const char *s, size_t maxlen);
276unsigned int atou(const char *s);
277
278/* tty.c */
279void puts(const char *);
280void putchar(int);
281int getchar(void);
282void kbd_flush(void);
283int getchar_timeout(void);
284
285/* video.c */
286void set_video(void);
287
288/* video-vesa.c */
289void vesa_store_edid(void);
290
291/* voyager.c */
292int query_voyager(void);
293
294#endif /* __ASSEMBLY__ */
295
296#endif /* BOOT_BOOT_H */
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
deleted file mode 100644
index 011b7a4993d4..000000000000
--- a/arch/i386/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
3 *
4 * modified by Drew Eckhardt
5 * modified by Bruce Evans (bde)
6 * modified by Chris Noe (May 1999) (as86 -> gas)
7 * gutted by H. Peter Anvin (Jan 2003)
8 *
9 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
10 * addresses must be multiplied by 16 to obtain their respective linear
11 * addresses. To avoid confusion, linear addresses are written using leading
12 * hex while segment addresses are written as segment:offset.
13 *
14 */
15
16#include <asm/boot.h>
17
18SETUPSECTS = 4 /* default nr of setup-sectors */
19BOOTSEG = 0x07C0 /* original address of boot-sector */
20INITSEG = DEF_INITSEG /* we move boot here - out of the way */
21SETUPSEG = DEF_SETUPSEG /* setup starts here */
22SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
23SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
24 /* to be loaded */
25ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
26SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
27
28#ifndef SVGA_MODE
29#define SVGA_MODE ASK_VGA
30#endif
31
32#ifndef RAMDISK
33#define RAMDISK 0
34#endif
35
36#ifndef ROOT_RDONLY
37#define ROOT_RDONLY 1
38#endif
39
40.code16
41.text
42
43.global _start
44_start:
45
46 # Normalize the start address
47 jmpl $BOOTSEG, $start2
48
49start2:
50 movw %cs, %ax
51 movw %ax, %ds
52 movw %ax, %es
53 movw %ax, %ss
54 movw $0x7c00, %sp
55 sti
56 cld
57
58 movw $bugger_off_msg, %si
59
60msg_loop:
61 lodsb
62 andb %al, %al
63 jz die
64 movb $0xe, %ah
65 movw $7, %bx
66 int $0x10
67 jmp msg_loop
68
69die:
70 # Allow the user to press a key, then reboot
71 xorw %ax, %ax
72 int $0x16
73 int $0x19
74
75 # int 0x19 should never return. In case it does anyway,
76 # invoke the BIOS reset code...
77 ljmp $0xf000,$0xfff0
78
79
80bugger_off_msg:
81 .ascii "Direct booting from floppy is no longer supported.\r\n"
82 .ascii "Please use a boot loader program instead.\r\n"
83 .ascii "\n"
84 .ascii "Remove disk and press any key to reboot . . .\r\n"
85 .byte 0
86
87
88 # Kernel attributes; used by setup
89
90 .org 497
91setup_sects: .byte SETUPSECTS
92root_flags: .word ROOT_RDONLY
93syssize: .word SYSSIZE
94swap_dev: .word SWAP_DEV
95ram_size: .word RAMDISK
96vid_mode: .word SVGA_MODE
97root_dev: .word ROOT_DEV
98boot_flag: .word 0xAA55
diff --git a/arch/i386/boot/cmdline.c b/arch/i386/boot/cmdline.c
new file mode 100644
index 000000000000..34bb778c4357
--- /dev/null
+++ b/arch/i386/boot/cmdline.c
@@ -0,0 +1,97 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/cmdline.c
13 *
14 * Simple command-line parser for early boot.
15 */
16
17#include "boot.h"
18
19static inline int myisspace(u8 c)
20{
21 return c <= ' '; /* Close enough approximation */
22}
23
24/*
25 * Find a non-boolean option, that is, "option=argument". In accordance
26 * with standard Linux practice, if this option is repeated, this returns
27 * the last instance on the command line.
28 *
29 * Returns the length of the argument (regardless of if it was
30 * truncated to fit in the buffer), or -1 on not found.
31 */
32int cmdline_find_option(const char *option, char *buffer, int bufsize)
33{
34 u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
35 addr_t cptr;
36 char c;
37 int len = -1;
38 const char *opptr = NULL;
39 char *bufptr = buffer;
40 enum {
41 st_wordstart, /* Start of word/after whitespace */
42 st_wordcmp, /* Comparing this word */
43 st_wordskip, /* Miscompare, skip */
44 st_bufcpy /* Copying this to buffer */
45 } state = st_wordstart;
46
47 if (!cmdline_ptr || cmdline_ptr >= 0x100000)
48 return -1; /* No command line, or inaccessible */
49
50 cptr = cmdline_ptr & 0xf;
51 set_fs(cmdline_ptr >> 4);
52
53 while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
54 switch (state) {
55 case st_wordstart:
56 if (myisspace(c))
57 break;
58
59 /* else */
60 state = st_wordcmp;
61 opptr = option;
62 /* fall through */
63
64 case st_wordcmp:
65 if (c == '=' && !*opptr) {
66 len = 0;
67 bufptr = buffer;
68 state = st_bufcpy;
69 } else if (myisspace(c)) {
70 state = st_wordstart;
71 } else if (c != *opptr++) {
72 state = st_wordskip;
73 }
74 break;
75
76 case st_wordskip:
77 if (myisspace(c))
78 state = st_wordstart;
79 break;
80
81 case st_bufcpy:
82 if (myisspace(c)) {
83 state = st_wordstart;
84 } else {
85 if (len < bufsize-1)
86 *bufptr++ = c;
87 len++;
88 }
89 break;
90 }
91 }
92
93 if (bufsize)
94 *bufptr = '\0';
95
96 return len;
97}
diff --git a/arch/i386/boot/code16gcc.h b/arch/i386/boot/code16gcc.h
new file mode 100644
index 000000000000..3bd848093b9d
--- /dev/null
+++ b/arch/i386/boot/code16gcc.h
@@ -0,0 +1,15 @@
1/*
2 * code16gcc.h
3 *
4 * This file is -include'd when compiling 16-bit C code.
5 * Note: this asm() needs to be emitted before gcc omits any code.
6 * Depending on gcc version, this requires -fno-unit-at-a-time or
7 * -fno-toplevel-reorder.
8 *
9 * Hopefully gcc will eventually have a real -m16 option so we can
10 * drop this hack long term.
11 */
12
13#ifndef __ASSEMBLY__
14asm(".code16gcc");
15#endif
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index a661217f33ec..189fa1dbefcc 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -9,9 +9,14 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
9EXTRA_AFLAGS := -traditional 9EXTRA_AFLAGS := -traditional
10 10
11LDFLAGS_vmlinux := -T 11LDFLAGS_vmlinux := -T
12CFLAGS_misc.o += -fPIC
13hostprogs-y := relocs 12hostprogs-y := relocs
14 13
14CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
15 -fno-strict-aliasing -fPIC \
16 $(call cc-option,-ffreestanding) \
17 $(call cc-option,-fno-stack-protector)
18LDFLAGS := -m elf_i386
19
15$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE 20$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
16 $(call if_changed,ld) 21 $(call if_changed,ld)
17 @: 22 @:
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
index 3517a32aaf41..f35ea2237522 100644
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -45,10 +45,10 @@ startup_32:
45 * at and where we were actually loaded at. This can only be done 45 * at and where we were actually loaded at. This can only be done
46 * with a short local call on x86. Nothing else will tell us what 46 * with a short local call on x86. Nothing else will tell us what
47 * address we are running at. The reserved chunk of the real-mode 47 * address we are running at. The reserved chunk of the real-mode
48 * data at 0x34-0x3f are used as the stack for this calculation. 48 * data at 0x1e4 (defined as a scratch field) are used as the stack
49 * Only 4 bytes are needed. 49 * for this calculation. Only 4 bytes are needed.
50 */ 50 */
51 leal 0x40(%esi), %esp 51 leal (0x1e4+4)(%esi), %esp
52 call 1f 52 call 1f
531: popl %ebp 531: popl %ebp
54 subl $1b, %ebp 54 subl $1b, %ebp
diff --git a/arch/i386/boot/copy.S b/arch/i386/boot/copy.S
new file mode 100644
index 000000000000..ef127e56a3cf
--- /dev/null
+++ b/arch/i386/boot/copy.S
@@ -0,0 +1,101 @@
1/* ----------------------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/copy.S
13 *
14 * Memory copy routines
15 */
16
17 .code16gcc
18 .text
19
20 .globl memcpy
21 .type memcpy, @function
22memcpy:
23 pushw %si
24 pushw %di
25 movw %ax, %di
26 movw %dx, %si
27 pushw %cx
28 shrw $2, %cx
29 rep; movsl
30 popw %cx
31 andw $3, %cx
32 rep; movsb
33 popw %di
34 popw %si
35 ret
36 .size memcpy, .-memcpy
37
38 .globl memset
39 .type memset, @function
40memset:
41 pushw %di
42 movw %ax, %di
43 movzbl %dl, %eax
44 imull $0x01010101,%eax
45 pushw %cx
46 shrw $2, %cx
47 rep; stosl
48 popw %cx
49 andw $3, %cx
50 rep; stosb
51 popw %di
52 ret
53 .size memset, .-memset
54
55 .globl copy_from_fs
56 .type copy_from_fs, @function
57copy_from_fs:
58 pushw %ds
59 pushw %fs
60 popw %ds
61 call memcpy
62 popw %ds
63 ret
64 .size copy_from_fs, .-copy_from_fs
65
66 .globl copy_to_fs
67 .type copy_to_fs, @function
68copy_to_fs:
69 pushw %es
70 pushw %fs
71 popw %es
72 call memcpy
73 popw %es
74 ret
75 .size copy_to_fs, .-copy_to_fs
76
77#if 0 /* Not currently used, but can be enabled as needed */
78
79 .globl copy_from_gs
80 .type copy_from_gs, @function
81copy_from_gs:
82 pushw %ds
83 pushw %gs
84 popw %ds
85 call memcpy
86 popw %ds
87 ret
88 .size copy_from_gs, .-copy_from_gs
89 .globl copy_to_gs
90
91 .type copy_to_gs, @function
92copy_to_gs:
93 pushw %es
94 pushw %gs
95 popw %es
96 call memcpy
97 popw %es
98 ret
99 .size copy_to_gs, .-copy_to_gs
100
101#endif
diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
new file mode 100644
index 000000000000..2a5c32da5852
--- /dev/null
+++ b/arch/i386/boot/cpu.c
@@ -0,0 +1,69 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/cpu.c
13 *
14 * Check for obligatory CPU features and abort if the features are not
15 * present.
16 */
17
18#include "boot.h"
19#include "bitops.h"
20#include <asm/cpufeature.h>
21
22static char *cpu_name(int level)
23{
24 static char buf[6];
25
26 if (level == 64) {
27 return "x86-64";
28 } else {
29 sprintf(buf, "i%d86", level);
30 return buf;
31 }
32}
33
34int validate_cpu(void)
35{
36 u32 *err_flags;
37 int cpu_level, req_level;
38
39 check_cpu(&cpu_level, &req_level, &err_flags);
40
41 if (cpu_level < req_level) {
42 printf("This kernel requires an %s CPU, ",
43 cpu_name(req_level));
44 printf("but only detected an %s CPU.\n",
45 cpu_name(cpu_level));
46 return -1;
47 }
48
49 if (err_flags) {
50 int i, j;
51 puts("This kernel requires the following features "
52 "not present on the CPU:\n");
53
54 for (i = 0; i < NCAPINTS; i++) {
55 u32 e = err_flags[i];
56
57 for (j = 0; j < 32; j++) {
58 if (e & 1)
59 printf("%d:%d ", i, j);
60
61 e >>= 1;
62 }
63 }
64 putchar('\n');
65 return -1;
66 } else {
67 return 0;
68 }
69}
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
new file mode 100644
index 000000000000..8b0f4473b083
--- /dev/null
+++ b/arch/i386/boot/cpucheck.c
@@ -0,0 +1,267 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/cpucheck.c
13 *
14 * Check for obligatory CPU features and abort if the features are not
15 * present. This code should be compilable as 16-, 32- or 64-bit
16 * code, so be very careful with types and inline assembly.
17 *
18 * This code should not contain any messages; that requires an
19 * additional wrapper.
20 *
21 * As written, this code is not safe for inclusion into the kernel
22 * proper (after FPU initialization, in particular).
23 */
24
25#ifdef _SETUP
26# include "boot.h"
27# include "bitops.h"
28#endif
29#include <linux/types.h>
30#include <asm/cpufeature.h>
31#include <asm/processor-flags.h>
32#include <asm/required-features.h>
33#include <asm/msr-index.h>
34
35struct cpu_features {
36 int level; /* Family, or 64 for x86-64 */
37 int model;
38 u32 flags[NCAPINTS];
39};
40
41static struct cpu_features cpu;
42static u32 cpu_vendor[3];
43static u32 err_flags[NCAPINTS];
44
45#ifdef CONFIG_X86_64
46static const int req_level = 64;
47#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY)
48static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
49#else
50static const int req_level = 3;
51#endif
52
53static const u32 req_flags[NCAPINTS] =
54{
55 REQUIRED_MASK0,
56 REQUIRED_MASK1,
57 REQUIRED_MASK2,
58 REQUIRED_MASK3,
59 REQUIRED_MASK4,
60 REQUIRED_MASK5,
61 REQUIRED_MASK6,
62 REQUIRED_MASK7,
63};
64
65#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
66
67static int is_amd(void)
68{
69 return cpu_vendor[0] == A32('A','u','t','h') &&
70 cpu_vendor[1] == A32('e','n','t','i') &&
71 cpu_vendor[2] == A32('c','A','M','D');
72}
73
74static int is_centaur(void)
75{
76 return cpu_vendor[0] == A32('C','e','n','t') &&
77 cpu_vendor[1] == A32('a','u','r','H') &&
78 cpu_vendor[2] == A32('a','u','l','s');
79}
80
81static int is_transmeta(void)
82{
83 return cpu_vendor[0] == A32('G','e','n','u') &&
84 cpu_vendor[1] == A32('i','n','e','T') &&
85 cpu_vendor[2] == A32('M','x','8','6');
86}
87
88static int has_fpu(void)
89{
90 u16 fcw = -1, fsw = -1;
91 u32 cr0;
92
93 asm("movl %%cr0,%0" : "=r" (cr0));
94 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
95 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
96 asm volatile("movl %0,%%cr0" : : "r" (cr0));
97 }
98
99 asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
100
101 return fsw == 0 && (fcw & 0x103f) == 0x003f;
102}
103
104static int has_eflag(u32 mask)
105{
106 u32 f0, f1;
107
108 asm("pushfl ; "
109 "pushfl ; "
110 "popl %0 ; "
111 "movl %0,%1 ; "
112 "xorl %2,%1 ; "
113 "pushl %1 ; "
114 "popfl ; "
115 "pushfl ; "
116 "popl %1 ; "
117 "popfl"
118 : "=r" (f0), "=r" (f1)
119 : "g" (mask));
120
121 return !!((f0^f1) & mask);
122}
123
124static void get_flags(void)
125{
126 u32 max_intel_level, max_amd_level;
127 u32 tfms;
128
129 if (has_fpu())
130 set_bit(X86_FEATURE_FPU, cpu.flags);
131
132 if (has_eflag(X86_EFLAGS_ID)) {
133 asm("cpuid"
134 : "=a" (max_intel_level),
135 "=b" (cpu_vendor[0]),
136 "=d" (cpu_vendor[1]),
137 "=c" (cpu_vendor[2])
138 : "a" (0));
139
140 if (max_intel_level >= 0x00000001 &&
141 max_intel_level <= 0x0000ffff) {
142 asm("cpuid"
143 : "=a" (tfms),
144 "=c" (cpu.flags[4]),
145 "=d" (cpu.flags[0])
146 : "a" (0x00000001)
147 : "ebx");
148 cpu.level = (tfms >> 8) & 15;
149 cpu.model = (tfms >> 4) & 15;
150 if (cpu.level >= 6)
151 cpu.model += ((tfms >> 16) & 0xf) << 4;
152 }
153
154 asm("cpuid"
155 : "=a" (max_amd_level)
156 : "a" (0x80000000)
157 : "ebx", "ecx", "edx");
158
159 if (max_amd_level >= 0x80000001 &&
160 max_amd_level <= 0x8000ffff) {
161 u32 eax = 0x80000001;
162 asm("cpuid"
163 : "+a" (eax),
164 "=c" (cpu.flags[6]),
165 "=d" (cpu.flags[1])
166 : : "ebx");
167 }
168 }
169}
170
171/* Returns a bitmask of which words we have error bits in */
172static int check_flags(void)
173{
174 u32 err;
175 int i;
176
177 err = 0;
178 for (i = 0; i < NCAPINTS; i++) {
179 err_flags[i] = req_flags[i] & ~cpu.flags[i];
180 if (err_flags[i])
181 err |= 1 << i;
182 }
183
184 return err;
185}
186
187/*
188 * Returns -1 on error.
189 *
190 * *cpu_level is set to the current CPU level; *req_level to the required
191 * level. x86-64 is considered level 64 for this purpose.
192 *
193 * *err_flags_ptr is set to the flags error array if there are flags missing.
194 */
195int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
196{
197 int err;
198
199 memset(&cpu.flags, 0, sizeof cpu.flags);
200 cpu.level = 3;
201
202 if (has_eflag(X86_EFLAGS_AC))
203 cpu.level = 4;
204
205 get_flags();
206 err = check_flags();
207
208 if (test_bit(X86_FEATURE_LM, cpu.flags))
209 cpu.level = 64;
210
211 if (err == 0x01 &&
212 !(err_flags[0] &
213 ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
214 is_amd()) {
215 /* If this is an AMD and we're only missing SSE+SSE2, try to
216 turn them on */
217
218 u32 ecx = MSR_K7_HWCR;
219 u32 eax, edx;
220
221 asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
222 eax &= ~(1 << 15);
223 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
224
225 get_flags(); /* Make sure it really did something */
226 err = check_flags();
227 } else if (err == 0x01 &&
228 !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
229 is_centaur() && cpu.model >= 6) {
230 /* If this is a VIA C3, we might have to enable CX8
231 explicitly */
232
233 u32 ecx = MSR_VIA_FCR;
234 u32 eax, edx;
235
236 asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
237 eax |= (1<<1)|(1<<7);
238 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
239
240 set_bit(X86_FEATURE_CX8, cpu.flags);
241 err = check_flags();
242 } else if (err == 0x01 && is_transmeta()) {
243 /* Transmeta might have masked feature bits in word 0 */
244
245 u32 ecx = 0x80860004;
246 u32 eax, edx;
247 u32 level = 1;
248
249 asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
250 asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
251 asm("cpuid"
252 : "+a" (level), "=d" (cpu.flags[0])
253 : : "ecx", "ebx");
254 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
255
256 err = check_flags();
257 }
258
259 if (err_flags_ptr)
260 *err_flags_ptr = err ? err_flags : NULL;
261 if (cpu_level_ptr)
262 *cpu_level_ptr = cpu.level;
263 if (req_level_ptr)
264 *req_level_ptr = req_level;
265
266 return (cpu.level < req_level || err) ? -1 : 0;
267}
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
deleted file mode 100644
index 34321368011a..000000000000
--- a/arch/i386/boot/edd.S
+++ /dev/null
@@ -1,231 +0,0 @@
1/*
2 * BIOS Enhanced Disk Drive support
3 * Copyright (C) 2002, 2003, 2004 Dell, Inc.
4 * by Matt Domsch <Matt_Domsch@dell.com> October 2002
5 * conformant to T13 Committee www.t13.org
6 * projects 1572D, 1484D, 1386D, 1226DT
7 * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
8 * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
9 * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
10 * March 2004
11 * Command line option parsing, Matt Domsch, November 2004
12 */
13
14#include <linux/edd.h>
15#include <asm/setup.h>
16
17#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
18
19# It is assumed that %ds == INITSEG here
20
21 movb $0, (EDD_MBR_SIG_NR_BUF)
22 movb $0, (EDDNR)
23
24# Check the command line for options:
25# edd=of disables EDD completely (edd=off)
26# edd=sk skips the MBR test (edd=skipmbr)
27# edd=on re-enables EDD (edd=on)
28
29 pushl %esi
30 movw $edd_mbr_sig_start, %di # Default to edd=on
31
32 movl %cs:(cmd_line_ptr), %esi
33 andl %esi, %esi
34 jz old_cl # Old boot protocol?
35
36# Convert to a real-mode pointer in fs:si
37 movl %esi, %eax
38 shrl $4, %eax
39 movw %ax, %fs
40 andw $0xf, %si
41 jmp have_cl_pointer
42
43# Old-style boot protocol?
44old_cl:
45 push %ds # aka INITSEG
46 pop %fs
47
48 cmpw $0xa33f, (0x20)
49 jne done_cl # No command line at all?
50 movw (0x22), %si # Pointer relative to INITSEG
51
52# fs:si has the pointer to the command line now
53have_cl_pointer:
54
55# Loop through kernel command line one byte at a time. Just in
56# case the loader is buggy and failed to null-terminate the command line
57# terminate if we get close enough to the end of the segment that we
58# cannot fit "edd=XX"...
59cl_atspace:
60 cmpw $-5, %si # Watch for segment wraparound
61 jae done_cl
62 movl %fs:(%si), %eax
63 andb %al, %al # End of line?
64 jz done_cl
65 cmpl $EDD_CL_EQUALS, %eax
66 jz found_edd_equals
67 cmpb $0x20, %al # <= space consider whitespace
68 ja cl_skipword
69 incw %si
70 jmp cl_atspace
71
72cl_skipword:
73 cmpw $-5, %si # Watch for segment wraparound
74 jae done_cl
75 movb %fs:(%si), %al # End of string?
76 andb %al, %al
77 jz done_cl
78 cmpb $0x20, %al
79 jbe cl_atspace
80 incw %si
81 jmp cl_skipword
82
83found_edd_equals:
84# only looking at first two characters after equals
85# late overrides early on the command line, so keep going after finding something
86 movw %fs:4(%si), %ax
87 cmpw $EDD_CL_OFF, %ax # edd=of
88 je do_edd_off
89 cmpw $EDD_CL_SKIP, %ax # edd=sk
90 je do_edd_skipmbr
91 cmpw $EDD_CL_ON, %ax # edd=on
92 je do_edd_on
93 jmp cl_skipword
94do_edd_skipmbr:
95 movw $edd_start, %di
96 jmp cl_skipword
97do_edd_off:
98 movw $edd_done, %di
99 jmp cl_skipword
100do_edd_on:
101 movw $edd_mbr_sig_start, %di
102 jmp cl_skipword
103
104done_cl:
105 popl %esi
106 jmpw *%di
107
108# Read the first sector of each BIOS disk device and store the 4-byte signature
109edd_mbr_sig_start:
110 movb $0x80, %dl # from device 80
111 movw $EDD_MBR_SIG_BUF, %bx # store buffer ptr in bx
112edd_mbr_sig_read:
113 movl $0xFFFFFFFF, %eax
114 movl %eax, (%bx) # assume failure
115 pushw %bx
116 movb $READ_SECTORS, %ah
117 movb $1, %al # read 1 sector
118 movb $0, %dh # at head 0
119 movw $1, %cx # cylinder 0, sector 0
120 pushw %es
121 pushw %ds
122 popw %es
123 movw $EDDBUF, %bx # disk's data goes into EDDBUF
124 pushw %dx # work around buggy BIOSes
125 stc # work around buggy BIOSes
126 int $0x13
127 sti # work around buggy BIOSes
128 popw %dx
129 popw %es
130 popw %bx
131 jc edd_mbr_sig_done # on failure, we're done.
132 cmpb $0, %ah # some BIOSes do not set CF
133 jne edd_mbr_sig_done # on failure, we're done.
134 movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
135 movl %eax, (%bx) # store success
136 incb (EDD_MBR_SIG_NR_BUF) # note that we stored something
137 incb %dl # increment to next device
138 addw $4, %bx # increment sig buffer ptr
139 cmpb $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF) # Out of space?
140 jb edd_mbr_sig_read # keep looping
141edd_mbr_sig_done:
142
143# Do the BIOS Enhanced Disk Drive calls
144# This consists of two calls:
145# int 13h ah=41h "Check Extensions Present"
146# int 13h ah=48h "Get Device Parameters"
147# int 13h ah=08h "Legacy Get Device Parameters"
148#
149# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
150# in the boot_params at EDDBUF. The first four bytes of which are
151# used to store the device number, interface support map and version
152# results from fn41. The next four bytes are used to store the legacy
153# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
154# store the results from fn48. Starting from device 80h, fn41, then fn48
155# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
156# Then the pointer is incremented to store the data for the next call.
157# This repeats until either a device doesn't exist, or until EDDMAXNR
158# devices have been stored.
159# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
160# the structure, and the fn41 and fn08 results are stored at offsets
161# from there. This removes the need to increment the pointer for
162# every store, and leaves it ready for the fn48 call.
163# A second one-byte buffer, EDDNR, in the boot_params stores
164# the number of BIOS devices which exist, up to EDDMAXNR.
165# In setup.c, copy_edd() stores both boot_params buffers away
166# for later use, as they would get overwritten otherwise.
167# This code is sensitive to the size of the structs in edd.h
168edd_start:
169 # %ds points to the bootsector
170 # result buffer for fn48
171 movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results
172 # kept just before that
173 movb $0x80, %dl # BIOS device 0x80
174
175edd_check_ext:
176 movb $CHECKEXTENSIONSPRESENT, %ah # Function 41
177 movw $EDDMAGIC1, %bx # magic
178 int $0x13 # make the call
179 jc edd_done # no more BIOS devices
180
181 cmpw $EDDMAGIC2, %bx # is magic right?
182 jne edd_next # nope, next...
183
184 movb %dl, %ds:-8(%si) # store device number
185 movb %ah, %ds:-7(%si) # store version
186 movw %cx, %ds:-6(%si) # store extensions
187 incb (EDDNR) # note that we stored something
188
189edd_get_device_params:
190 movw $EDDPARMSIZE, %ds:(%si) # put size
191 movw $0x0, %ds:2(%si) # work around buggy BIOSes
192 movb $GETDEVICEPARAMETERS, %ah # Function 48
193 int $0x13 # make the call
194 # Don't check for fail return
195 # it doesn't matter.
196edd_get_legacy_chs:
197 xorw %ax, %ax
198 movw %ax, %ds:-4(%si)
199 movw %ax, %ds:-2(%si)
200 # Ralf Brown's Interrupt List says to set ES:DI to
201 # 0000h:0000h "to guard against BIOS bugs"
202 pushw %es
203 movw %ax, %es
204 movw %ax, %di
205 pushw %dx # legacy call clobbers %dl
206 movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
207 int $0x13 # make the call
208 jc edd_legacy_done # failed
209 movb %cl, %al # Low 6 bits are max
210 andb $0x3F, %al # sector number
211 movb %al, %ds:-1(%si) # Record max sect
212 movb %dh, %ds:-2(%si) # Record max head number
213 movb %ch, %al # Low 8 bits of max cyl
214 shr $6, %cl
215 movb %cl, %ah # High 2 bits of max cyl
216 movw %ax, %ds:-4(%si)
217
218edd_legacy_done:
219 popw %dx
220 popw %es
221 movw %si, %ax # increment si
222 addw $EDDPARMSIZE+EDDEXTSIZE, %ax
223 movw %ax, %si
224
225edd_next:
226 incb %dl # increment to next device
227 cmpb $EDDMAXNR, (EDDNR) # Out of space?
228 jb edd_check_ext # keep looping
229
230edd_done:
231#endif
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c
new file mode 100644
index 000000000000..25a282494f4c
--- /dev/null
+++ b/arch/i386/boot/edd.c
@@ -0,0 +1,196 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/edd.c
13 *
14 * Get EDD BIOS disk information
15 */
16
17#include "boot.h"
18#include <linux/edd.h>
19
20#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
21
22struct edd_dapa {
23 u8 pkt_size;
24 u8 rsvd;
25 u16 sector_cnt;
26 u16 buf_off, buf_seg;
27 u64 lba;
28 u64 buf_lin_addr;
29};
30
31/*
32 * Read the MBR (first sector) from a specific device.
33 */
34static int read_mbr(u8 devno, void *buf)
35{
36 struct edd_dapa dapa;
37 u16 ax, bx, cx, dx, si;
38
39 memset(&dapa, 0, sizeof dapa);
40 dapa.pkt_size = sizeof(dapa);
41 dapa.sector_cnt = 1;
42 dapa.buf_off = (size_t)buf;
43 dapa.buf_seg = ds();
44 /* dapa.lba = 0; */
45
46 ax = 0x4200; /* Extended Read */
47 si = (size_t)&dapa;
48 dx = devno;
49 asm("pushfl; stc; int $0x13; setc %%al; popfl"
50 : "+a" (ax), "+S" (si), "+d" (dx)
51 : "m" (dapa)
52 : "ebx", "ecx", "edi", "memory");
53
54 if (!(u8)ax)
55 return 0; /* OK */
56
57 ax = 0x0201; /* Legacy Read, one sector */
58 cx = 0x0001; /* Sector 0-0-1 */
59 dx = devno;
60 bx = (size_t)buf;
61 asm("pushfl; stc; int $0x13; setc %%al; popfl"
62 : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
63 : : "esi", "edi", "memory");
64
65 return -(u8)ax; /* 0 or -1 */
66}
67
68static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
69{
70 int sector_size;
71 char *mbrbuf_ptr, *mbrbuf_end;
72 u32 mbrsig;
73 u32 buf_base, mbr_base;
74 extern char _end[];
75 static char mbr_buf[1024];
76
77 sector_size = ei->params.bytes_per_sector;
78 if (!sector_size)
79 sector_size = 512; /* Best available guess */
80
81 buf_base = (ds() << 4) + (u32)&_end;
82 mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
83 mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
84 mbrbuf_end = mbrbuf_ptr + sector_size;
85
86 if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
87 return 0;
88 if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
89 return 0;
90
91 if (read_mbr(devno, mbrbuf_ptr))
92 return 0;
93
94 mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
95 return mbrsig;
96}
97
98static int get_edd_info(u8 devno, struct edd_info *ei)
99{
100 u16 ax, bx, cx, dx, di;
101
102 memset(ei, 0, sizeof *ei);
103
104 /* Check Extensions Present */
105
106 ax = 0x4100;
107 bx = EDDMAGIC1;
108 dx = devno;
109 asm("pushfl; stc; int $0x13; setc %%al; popfl"
110 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
111 : : "esi", "edi");
112
113 if ((u8)ax)
114 return -1; /* No extended information */
115
116 if (bx != EDDMAGIC2)
117 return -1;
118
119 ei->device = devno;
120 ei->version = ax >> 8; /* EDD version number */
121 ei->interface_support = cx; /* EDD functionality subsets */
122
123 /* Extended Get Device Parameters */
124
125 ei->params.length = sizeof(ei->params);
126 ax = 0x4800;
127 dx = devno;
128 asm("pushfl; int $0x13; popfl"
129 : "+a" (ax), "+d" (dx)
130 : "S" (&ei->params)
131 : "ebx", "ecx", "edi");
132
133 /* Get legacy CHS parameters */
134
135 /* Ralf Brown recommends setting ES:DI to 0:0 */
136 ax = 0x0800;
137 dx = devno;
138 di = 0;
139 asm("pushw %%es; "
140 "movw %%di,%%es; "
141 "pushfl; stc; int $0x13; setc %%al; popfl; "
142 "popw %%es"
143 : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
144 : : "esi");
145
146 if ((u8)ax == 0) {
147 ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
148 ei->legacy_max_head = dx >> 8;
149 ei->legacy_sectors_per_track = cx & 0x3f;
150 }
151
152 return 0;
153}
154
155void query_edd(void)
156{
157 char eddarg[8];
158 int do_mbr = 1;
159 int do_edd = 1;
160 int devno;
161 struct edd_info ei, *edp;
162
163 if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
164 if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
165 do_mbr = 0;
166 else if (!strcmp(eddarg, "off"))
167 do_edd = 0;
168 }
169
170 edp = (struct edd_info *)boot_params.eddbuf;
171
172 if (!do_edd)
173 return;
174
175 for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
176 /*
177 * Scan the BIOS-supported hard disks and query EDD
178 * information...
179 */
180 get_edd_info(devno, &ei);
181
182 if (boot_params.eddbuf_entries < EDDMAXNR) {
183 memcpy(edp, &ei, sizeof ei);
184 edp++;
185 boot_params.eddbuf_entries++;
186 }
187
188 if (do_mbr) {
189 u32 mbr_sig;
190 mbr_sig = read_mbr_sig(devno, &ei);
191 boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
192 }
193 }
194}
195
196#endif
diff --git a/arch/i386/boot/header.S b/arch/i386/boot/header.S
new file mode 100644
index 000000000000..6b9923fb6eae
--- /dev/null
+++ b/arch/i386/boot/header.S
@@ -0,0 +1,283 @@
1/*
2 * header.S
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * Based on bootsect.S and setup.S
7 * modified by more people than can be counted
8 *
9 * Rewritten as a common file by H. Peter Anvin (Apr 2007)
10 *
11 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
12 * addresses must be multiplied by 16 to obtain their respective linear
13 * addresses. To avoid confusion, linear addresses are written using leading
14 * hex while segment addresses are written as segment:offset.
15 *
16 */
17
18#include <asm/segment.h>
19#include <linux/utsrelease.h>
20#include <asm/boot.h>
21#include <asm/e820.h>
22#include <asm/page.h>
23#include <asm/setup.h>
24#include "boot.h"
25
26SETUPSECTS = 4 /* default nr of setup-sectors */
27BOOTSEG = 0x07C0 /* original address of boot-sector */
28SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
29SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
30 /* to be loaded */
31ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
32SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
33
34#ifndef SVGA_MODE
35#define SVGA_MODE ASK_VGA
36#endif
37
38#ifndef RAMDISK
39#define RAMDISK 0
40#endif
41
42#ifndef ROOT_RDONLY
43#define ROOT_RDONLY 1
44#endif
45
46 .code16
47 .section ".bstext", "ax"
48
49 .global bootsect_start
50bootsect_start:
51
52 # Normalize the start address
53 ljmp $BOOTSEG, $start2
54
55start2:
56 movw %cs, %ax
57 movw %ax, %ds
58 movw %ax, %es
59 movw %ax, %ss
60 xorw %sp, %sp
61 sti
62 cld
63
64 movw $bugger_off_msg, %si
65
66msg_loop:
67 lodsb
68 andb %al, %al
69 jz bs_die
70 movb $0xe, %ah
71 movw $7, %bx
72 int $0x10
73 jmp msg_loop
74
75bs_die:
76 # Allow the user to press a key, then reboot
77 xorw %ax, %ax
78 int $0x16
79 int $0x19
80
81 # int 0x19 should never return. In case it does anyway,
82 # invoke the BIOS reset code...
83 ljmp $0xf000,$0xfff0
84
85 .section ".bsdata", "a"
86bugger_off_msg:
87 .ascii "Direct booting from floppy is no longer supported.\r\n"
88 .ascii "Please use a boot loader program instead.\r\n"
89 .ascii "\n"
90 .ascii "Remove disk and press any key to reboot . . .\r\n"
91 .byte 0
92
93
94 # Kernel attributes; used by setup. This is part 1 of the
95 # header, from the old boot sector.
96
97 .section ".header", "a"
98 .globl hdr
99hdr:
100setup_sects: .byte SETUPSECTS
101root_flags: .word ROOT_RDONLY
102syssize: .long SYSSIZE
103ram_size: .word RAMDISK
104vid_mode: .word SVGA_MODE
105root_dev: .word ROOT_DEV
106boot_flag: .word 0xAA55
107
108 # offset 512, entry point
109
110 .globl _start
111_start:
112 # Explicitly enter this as bytes, or the assembler
113 # tries to generate a 3-byte jump here, which causes
114 # everything else to push off to the wrong offset.
115 .byte 0xeb # short (2-byte) jump
116 .byte start_of_setup-1f
1171:
118
119 # Part 2 of the header, from the old setup.S
120
121 .ascii "HdrS" # header signature
122 .word 0x0206 # header version number (>= 0x0105)
123 # or else old loadlin-1.5 will fail)
124 .globl realmode_swtch
125realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
126start_sys_seg: .word SYSSEG
127 .word kernel_version-512 # pointing to kernel version string
128 # above section of header is compatible
129 # with loadlin-1.5 (header v1.5). Don't
130 # change it.
131
132type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
133 # Bootlin, SYSLX, bootsect...)
134 # See Documentation/i386/boot.txt for
135 # assigned ids
136
137# flags, unused bits must be zero (RFU) bit within loadflags
138loadflags:
139LOADED_HIGH = 1 # If set, the kernel is loaded high
140CAN_USE_HEAP = 0x80 # If set, the loader also has set
141 # heap_end_ptr to tell how much
142 # space behind setup.S can be used for
143 # heap purposes.
144 # Only the loader knows what is free
145#ifndef __BIG_KERNEL__
146 .byte 0
147#else
148 .byte LOADED_HIGH
149#endif
150
151setup_move_size: .word 0x8000 # size to move, when setup is not
152 # loaded at 0x90000. We will move setup
153 # to 0x90000 then just before jumping
154 # into the kernel. However, only the
155 # loader knows how much data behind
156 # us also needs to be loaded.
157
158code32_start: # here loaders can put a different
159 # start address for 32-bit code.
160#ifndef __BIG_KERNEL__
161 .long 0x1000 # 0x1000 = default for zImage
162#else
163 .long 0x100000 # 0x100000 = default for big kernel
164#endif
165
166ramdisk_image: .long 0 # address of loaded ramdisk image
167 # Here the loader puts the 32-bit
168 # address where it loaded the image.
169 # This only will be read by the kernel.
170
171ramdisk_size: .long 0 # its size in bytes
172
173bootsect_kludge:
174 .long 0 # obsolete
175
176heap_end_ptr: .word _end+1024 # (Header version 0x0201 or later)
177 # space from here (exclusive) down to
178 # end of setup code can be used by setup
179 # for local heap purposes.
180
181pad1: .word 0
182cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
183 # If nonzero, a 32-bit pointer
184 # to the kernel command line.
185 # The command line should be
186 # located between the start of
187 # setup and the end of low
188 # memory (0xa0000), or it may
189 # get overwritten before it
190 # gets read. If this field is
191 # used, there is no longer
192 # anything magical about the
193 # 0x90000 segment; the setup
194 # can be located anywhere in
195 # low memory 0x10000 or higher.
196
197ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
198 # (Header version 0x0203 or later)
199 # The highest safe address for
200 # the contents of an initrd
201
202kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
203 #required for protected mode
204 #kernel
205#ifdef CONFIG_RELOCATABLE
206relocatable_kernel: .byte 1
207#else
208relocatable_kernel: .byte 0
209#endif
210pad2: .byte 0
211pad3: .word 0
212
213cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
214 #added with boot protocol
215 #version 2.06
216
217# End of setup header #####################################################
218
219 .section ".inittext", "ax"
220start_of_setup:
221#ifdef SAFE_RESET_DISK_CONTROLLER
222# Reset the disk controller.
223 movw $0x0000, %ax # Reset disk controller
224 movb $0x80, %dl # All disks
225 int $0x13
226#endif
227
228# We will have entired with %cs = %ds+0x20, normalize %cs so
229# it is on par with the other segments.
230 pushw %ds
231 pushw $setup2
232 lretw
233
234setup2:
235# Force %es = %ds
236 movw %ds, %ax
237 movw %ax, %es
238 cld
239
240# Stack paranoia: align the stack and make sure it is good
241# for both 16- and 32-bit references. In particular, if we
242# were meant to have been using the full 16-bit segment, the
243# caller might have set %sp to zero, which breaks %esp-based
244# references.
245 andw $~3, %sp # dword align (might as well...)
246 jnz 1f
247 movw $0xfffc, %sp # Make sure we're not zero
2481: movzwl %sp, %esp # Clear upper half of %esp
249 sti
250
251# Check signature at end of setup
252 cmpl $0x5a5aaa55, setup_sig
253 jne setup_bad
254
255# Zero the bss
256 movw $__bss_start, %di
257 movw $_end+3, %cx
258 xorl %eax, %eax
259 subw %di, %cx
260 shrw $2, %cx
261 rep; stosl
262
263# Jump to C code (should not return)
264 calll main
265
266# Setup corrupt somehow...
267setup_bad:
268 movl $setup_corrupt, %eax
269 calll puts
270 # Fall through...
271
272 .globl die
273 .type die, @function
274die:
275 hlt
276 jmp die
277
278 .size die, .-due
279
280 .section ".initdata", "a"
281setup_corrupt:
282 .byte 7
283 .string "No setup signature found..."
diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
new file mode 100644
index 000000000000..7f01f96c4fb8
--- /dev/null
+++ b/arch/i386/boot/main.c
@@ -0,0 +1,161 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/main.c
13 *
14 * Main module for the real-mode kernel code
15 */
16
17#include "boot.h"
18
19struct boot_params boot_params __attribute__((aligned(16)));
20
21char *HEAP = _end;
22char *heap_end = _end; /* Default end of heap = no heap */
23
24/*
25 * Copy the header into the boot parameter block. Since this
26 * screws up the old-style command line protocol, adjust by
27 * filling in the new-style command line pointer instead.
28 */
29#define OLD_CL_MAGIC 0xA33F
30#define OLD_CL_ADDRESS 0x20
31
32static void copy_boot_params(void)
33{
34 struct old_cmdline {
35 u16 cl_magic;
36 u16 cl_offset;
37 };
38 const struct old_cmdline * const oldcmd =
39 (const struct old_cmdline *)OLD_CL_ADDRESS;
40
41 BUILD_BUG_ON(sizeof boot_params != 4096);
42 memcpy(&boot_params.hdr, &hdr, sizeof hdr);
43
44 if (!boot_params.hdr.cmd_line_ptr &&
45 oldcmd->cl_magic == OLD_CL_MAGIC) {
46 /* Old-style command line protocol. */
47 u16 cmdline_seg;
48
49 /* Figure out if the command line falls in the region
50 of memory that an old kernel would have copied up
51 to 0x90000... */
52 if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
53 cmdline_seg = ds();
54 else
55 cmdline_seg = 0x9000;
56
57 boot_params.hdr.cmd_line_ptr =
58 (cmdline_seg << 4) + oldcmd->cl_offset;
59 }
60}
61
62/*
63 * Set the keyboard repeat rate to maximum. Unclear why this
64 * is done here; this might be possible to kill off as stale code.
65 */
66static void keyboard_set_repeat(void)
67{
68 u16 ax = 0x0305;
69 u16 bx = 0;
70 asm volatile("int $0x16"
71 : "+a" (ax), "+b" (bx)
72 : : "ecx", "edx", "esi", "edi");
73}
74
75/*
76 * Get Intel SpeedStep IST information.
77 */
78static void query_speedstep_ist(void)
79{
80 asm("int $0x15"
81 : "=a" (boot_params.speedstep_info[0]),
82 "=b" (boot_params.speedstep_info[1]),
83 "=c" (boot_params.speedstep_info[2]),
84 "=d" (boot_params.speedstep_info[3])
85 : "a" (0x0000e980), /* IST Support */
86 "d" (0x47534943)); /* Request value */
87}
88
89/*
90 * Tell the BIOS what CPU mode we intend to run in.
91 */
92static void set_bios_mode(void)
93{
94#ifdef CONFIG_X86_64
95 u32 eax, ebx;
96
97 eax = 0xec00;
98 ebx = 2;
99 asm volatile("int $0x15"
100 : "+a" (eax), "+b" (ebx)
101 : : "ecx", "edx", "esi", "edi");
102#endif
103}
104
105void main(void)
106{
107 /* First, copy the boot header into the "zeropage" */
108 copy_boot_params();
109
110 /* End of heap check */
111 if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
112 heap_end = (char *)(boot_params.hdr.heap_end_ptr
113 +0x200-STACK_SIZE);
114 } else {
115 /* Boot protocol 2.00 only, no heap available */
116 puts("WARNING: Ancient bootloader, some functionality "
117 "may be limited!\n");
118 }
119
120 /* Make sure we have all the proper CPU support */
121 if (validate_cpu()) {
122 puts("Unable to boot - please use a kernel appropriate "
123 "for your CPU.\n");
124 die();
125 }
126
127 /* Tell the BIOS what CPU mode we intend to run in. */
128 set_bios_mode();
129
130 /* Detect memory layout */
131 detect_memory();
132
133 /* Set keyboard repeat rate (why?) */
134 keyboard_set_repeat();
135
136 /* Set the video mode */
137 set_video();
138
139 /* Query MCA information */
140 query_mca();
141
142 /* Voyager */
143#ifdef CONFIG_X86_VOYAGER
144 query_voyager();
145#endif
146
147 /* Query SpeedStep IST information */
148 query_speedstep_ist();
149
150 /* Query APM information */
151#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
152 query_apm_bios();
153#endif
154
155 /* Query EDD information */
156#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
157 query_edd();
158#endif
159 /* Do the last things and invoke protected mode */
160 go_to_protected_mode();
161}
diff --git a/arch/i386/boot/mca.c b/arch/i386/boot/mca.c
new file mode 100644
index 000000000000..9b68bd1aef19
--- /dev/null
+++ b/arch/i386/boot/mca.c
@@ -0,0 +1,43 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/mca.c
13 *
14 * Get the MCA system description table
15 */
16
17#include "boot.h"
18
19int query_mca(void)
20{
21 u8 err;
22 u16 es, bx, len;
23
24 asm("pushw %%es ; "
25 "int $0x15 ; "
26 "setc %0 ; "
27 "movw %%es, %1 ; "
28 "popw %%es"
29 : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
30 : "a" (0xc000));
31
32 if (err)
33 return -1; /* No MCA present */
34
35 set_fs(es);
36 len = rdfs16(bx);
37
38 if (len > sizeof(boot_params.sys_desc_table))
39 len = sizeof(boot_params.sys_desc_table);
40
41 copy_from_fs(&boot_params.sys_desc_table, bx, len);
42 return 0;
43}
diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c
new file mode 100644
index 000000000000..1a2e62db8bed
--- /dev/null
+++ b/arch/i386/boot/memory.c
@@ -0,0 +1,99 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/memory.c
13 *
14 * Memory detection code
15 */
16
17#include "boot.h"
18
19#define SMAP 0x534d4150 /* ASCII "SMAP" */
20
21static int detect_memory_e820(void)
22{
23 u32 next = 0;
24 u32 size, id;
25 u8 err;
26 struct e820entry *desc = boot_params.e820_map;
27
28 do {
29 size = sizeof(struct e820entry);
30 id = SMAP;
31 asm("int $0x15; setc %0"
32 : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
33 "=m" (*desc)
34 : "D" (desc), "a" (0xe820));
35
36 if (err || id != SMAP)
37 break;
38
39 boot_params.e820_entries++;
40 desc++;
41 } while (next && boot_params.e820_entries < E820MAX);
42
43 return boot_params.e820_entries;
44}
45
46static int detect_memory_e801(void)
47{
48 u16 ax, bx, cx, dx;
49 u8 err;
50
51 bx = cx = dx = 0;
52 ax = 0xe801;
53 asm("stc; int $0x15; setc %0"
54 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
55
56 if (err)
57 return -1;
58
59 /* Do we really need to do this? */
60 if (cx || dx) {
61 ax = cx;
62 bx = dx;
63 }
64
65 if (ax > 15*1024)
66 return -1; /* Bogus! */
67
68 /* This ignores memory above 16MB if we have a memory hole
69 there. If someone actually finds a machine with a memory
70 hole at 16MB and no support for 0E820h they should probably
71 generate a fake e820 map. */
72 boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
73
74 return 0;
75}
76
77static int detect_memory_88(void)
78{
79 u16 ax;
80 u8 err;
81
82 ax = 0x8800;
83 asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
84
85 boot_params.screen_info.ext_mem_k = ax;
86
87 return -err;
88}
89
90int detect_memory(void)
91{
92 if (detect_memory_e820() > 0)
93 return 0;
94
95 if (!detect_memory_e801())
96 return 0;
97
98 return detect_memory_88();
99}
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
new file mode 100644
index 000000000000..3fa53e15ed77
--- /dev/null
+++ b/arch/i386/boot/pm.c
@@ -0,0 +1,170 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/pm.c
13 *
14 * Prepare the machine for transition to protected mode.
15 */
16
17#include "boot.h"
18#include <asm/segment.h>
19
20/*
21 * Invoke the realmode switch hook if present; otherwise
22 * disable all interrupts.
23 */
24static void realmode_switch_hook(void)
25{
26 if (boot_params.hdr.realmode_swtch) {
27 asm volatile("lcallw *%0"
28 : : "m" (boot_params.hdr.realmode_swtch)
29 : "eax", "ebx", "ecx", "edx");
30 } else {
31 asm volatile("cli");
32 outb(0x80, 0x70); /* Disable NMI */
33 io_delay();
34 }
35}
36
37/*
38 * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
39 * A bzImage kernel is loaded and runs at 0x100000.
40 */
41static void move_kernel_around(void)
42{
43 /* Note: rely on the compile-time option here rather than
44 the LOADED_HIGH flag. The Qemu kernel loader unconditionally
45 sets the loadflags to zero. */
46#ifndef __BIG_KERNEL__
47 u16 dst_seg, src_seg;
48 u32 syssize;
49
50 dst_seg = 0x1000 >> 4;
51 src_seg = 0x10000 >> 4;
52 syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraphs */
53
54 while (syssize) {
55 int paras = (syssize >= 0x1000) ? 0x1000 : syssize;
56 int dwords = paras << 2;
57
58 asm volatile("pushw %%es ; "
59 "pushw %%ds ; "
60 "movw %1,%%es ; "
61 "movw %2,%%ds ; "
62 "xorw %%di,%%di ; "
63 "xorw %%si,%%si ; "
64 "rep;movsl ; "
65 "popw %%ds ; "
66 "popw %%es"
67 : "+c" (dwords)
68 : "rm" (dst_seg), "rm" (src_seg)
69 : "esi", "edi");
70
71 syssize -= paras;
72 dst_seg += paras;
73 src_seg += paras;
74 }
75#endif
76}
77
78/*
79 * Disable all interrupts at the legacy PIC.
80 */
81static void mask_all_interrupts(void)
82{
83 outb(0xff, 0xa1); /* Mask all interrupts on the seconday PIC */
84 io_delay();
85 outb(0xfb, 0x21); /* Mask all but cascade on the primary PIC */
86 io_delay();
87}
88
89/*
90 * Reset IGNNE# if asserted in the FPU.
91 */
92static void reset_coprocessor(void)
93{
94 outb(0, 0xf0);
95 io_delay();
96 outb(0, 0xf1);
97 io_delay();
98}
99
100/*
101 * Set up the GDT
102 */
103#define GDT_ENTRY(flags,base,limit) \
104 (((u64)(base & 0xff000000) << 32) | \
105 ((u64)flags << 40) | \
106 ((u64)(limit & 0x00ff0000) << 32) | \
107 ((u64)(base & 0x00ffff00) << 16) | \
108 ((u64)(limit & 0x0000ffff)))
109
110struct gdt_ptr {
111 u16 len;
112 u32 ptr;
113} __attribute__((packed));
114
115static void setup_gdt(void)
116{
117 /* There are machines which are known to not boot with the GDT
118 being 8-byte unaligned. Intel recommends 16 byte alignment. */
119 static const u64 boot_gdt[] __attribute__((aligned(16))) = {
120 /* CS: code, read/execute, 4 GB, base 0 */
121 [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
122 /* DS: data, read/write, 4 GB, base 0 */
123 [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
124 };
125 struct gdt_ptr gdt;
126
127 gdt.len = sizeof(boot_gdt)-1;
128 gdt.ptr = (u32)&boot_gdt + (ds() << 4);
129
130 asm volatile("lgdtl %0" : : "m" (gdt));
131}
132
133/*
134 * Set up the IDT
135 */
136static void setup_idt(void)
137{
138 static const struct gdt_ptr null_idt = {0, 0};
139 asm volatile("lidtl %0" : : "m" (null_idt));
140}
141
142/*
143 * Actual invocation sequence
144 */
145void go_to_protected_mode(void)
146{
147 /* Hook before leaving real mode, also disables interrupts */
148 realmode_switch_hook();
149
150 /* Move the kernel/setup to their final resting places */
151 move_kernel_around();
152
153 /* Enable the A20 gate */
154 if (enable_a20()) {
155 puts("A20 gate not responding, unable to boot...\n");
156 die();
157 }
158
159 /* Reset coprocessor (IGNNE#) */
160 reset_coprocessor();
161
162 /* Mask all interrupts in the PIC */
163 mask_all_interrupts();
164
165 /* Actual transition to protected mode... */
166 setup_idt();
167 setup_gdt();
168 protected_mode_jump(boot_params.hdr.code32_start,
169 (u32)&boot_params + (ds() << 4));
170}
diff --git a/arch/i386/boot/pmjump.S b/arch/i386/boot/pmjump.S
new file mode 100644
index 000000000000..2e559233725a
--- /dev/null
+++ b/arch/i386/boot/pmjump.S
@@ -0,0 +1,54 @@
1/* ----------------------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/pmjump.S
13 *
14 * The actual transition into protected mode
15 */
16
17#include <asm/boot.h>
18#include <asm/segment.h>
19
20 .text
21
22 .globl protected_mode_jump
23 .type protected_mode_jump, @function
24
25 .code16
26
27/*
28 * void protected_mode_jump(u32 entrypoint, u32 bootparams);
29 */
30protected_mode_jump:
31 xorl %ebx, %ebx # Flag to indicate this is a boot
32 movl %edx, %esi # Pointer to boot_params table
33 movl %eax, 2f # Patch ljmpl instruction
34 jmp 1f # Short jump to flush instruction q.
35
361:
37 movw $__BOOT_DS, %cx
38
39 movl %cr0, %edx
40 orb $1, %dl # Protected mode (PE) bit
41 movl %edx, %cr0
42
43 movw %cx, %ds
44 movw %cx, %es
45 movw %cx, %fs
46 movw %cx, %gs
47 movw %cx, %ss
48
49 # Jump to the 32-bit entrypoint
50 .byte 0x66, 0xea # ljmpl opcode
512: .long 0 # offset
52 .word __BOOT_CS # segment
53
54 .size protected_mode_jump, .-protected_mode_jump
diff --git a/arch/i386/boot/printf.c b/arch/i386/boot/printf.c
new file mode 100644
index 000000000000..1a09f9309d3c
--- /dev/null
+++ b/arch/i386/boot/printf.c
@@ -0,0 +1,307 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/printf.c
13 *
14 * Oh, it's a waste of space, but oh-so-yummy for debugging. This
15 * version of printf() does not include 64-bit support. "Live with
16 * it."
17 *
18 */
19
20#include "boot.h"
21
22static int skip_atoi(const char **s)
23{
24 int i = 0;
25
26 while (isdigit(**s))
27 i = i * 10 + *((*s)++) - '0';
28 return i;
29}
30
31#define ZEROPAD 1 /* pad with zero */
32#define SIGN 2 /* unsigned/signed long */
33#define PLUS 4 /* show plus */
34#define SPACE 8 /* space if plus */
35#define LEFT 16 /* left justified */
36#define SPECIAL 32 /* 0x */
37#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
38
39#define do_div(n,base) ({ \
40int __res; \
41__res = ((unsigned long) n) % (unsigned) base; \
42n = ((unsigned long) n) / (unsigned) base; \
43__res; })
44
45static char *number(char *str, long num, int base, int size, int precision,
46 int type)
47{
48 char c, sign, tmp[66];
49 const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
50 int i;
51
52 if (type & LARGE)
53 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
54 if (type & LEFT)
55 type &= ~ZEROPAD;
56 if (base < 2 || base > 36)
57 return 0;
58 c = (type & ZEROPAD) ? '0' : ' ';
59 sign = 0;
60 if (type & SIGN) {
61 if (num < 0) {
62 sign = '-';
63 num = -num;
64 size--;
65 } else if (type & PLUS) {
66 sign = '+';
67 size--;
68 } else if (type & SPACE) {
69 sign = ' ';
70 size--;
71 }
72 }
73 if (type & SPECIAL) {
74 if (base == 16)
75 size -= 2;
76 else if (base == 8)
77 size--;
78 }
79 i = 0;
80 if (num == 0)
81 tmp[i++] = '0';
82 else
83 while (num != 0)
84 tmp[i++] = digits[do_div(num, base)];
85 if (i > precision)
86 precision = i;
87 size -= precision;
88 if (!(type & (ZEROPAD + LEFT)))
89 while (size-- > 0)
90 *str++ = ' ';
91 if (sign)
92 *str++ = sign;
93 if (type & SPECIAL) {
94 if (base == 8)
95 *str++ = '0';
96 else if (base == 16) {
97 *str++ = '0';
98 *str++ = digits[33];
99 }
100 }
101 if (!(type & LEFT))
102 while (size-- > 0)
103 *str++ = c;
104 while (i < precision--)
105 *str++ = '0';
106 while (i-- > 0)
107 *str++ = tmp[i];
108 while (size-- > 0)
109 *str++ = ' ';
110 return str;
111}
112
113int vsprintf(char *buf, const char *fmt, va_list args)
114{
115 int len;
116 unsigned long num;
117 int i, base;
118 char *str;
119 const char *s;
120
121 int flags; /* flags to number() */
122
123 int field_width; /* width of output field */
124 int precision; /* min. # of digits for integers; max
125 number of chars for from string */
126 int qualifier; /* 'h', 'l', or 'L' for integer fields */
127
128 for (str = buf; *fmt; ++fmt) {
129 if (*fmt != '%') {
130 *str++ = *fmt;
131 continue;
132 }
133
134 /* process flags */
135 flags = 0;
136 repeat:
137 ++fmt; /* this also skips first '%' */
138 switch (*fmt) {
139 case '-':
140 flags |= LEFT;
141 goto repeat;
142 case '+':
143 flags |= PLUS;
144 goto repeat;
145 case ' ':
146 flags |= SPACE;
147 goto repeat;
148 case '#':
149 flags |= SPECIAL;
150 goto repeat;
151 case '0':
152 flags |= ZEROPAD;
153 goto repeat;
154 }
155
156 /* get field width */
157 field_width = -1;
158 if (isdigit(*fmt))
159 field_width = skip_atoi(&fmt);
160 else if (*fmt == '*') {
161 ++fmt;
162 /* it's the next argument */
163 field_width = va_arg(args, int);
164 if (field_width < 0) {
165 field_width = -field_width;
166 flags |= LEFT;
167 }
168 }
169
170 /* get the precision */
171 precision = -1;
172 if (*fmt == '.') {
173 ++fmt;
174 if (isdigit(*fmt))
175 precision = skip_atoi(&fmt);
176 else if (*fmt == '*') {
177 ++fmt;
178 /* it's the next argument */
179 precision = va_arg(args, int);
180 }
181 if (precision < 0)
182 precision = 0;
183 }
184
185 /* get the conversion qualifier */
186 qualifier = -1;
187 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
188 qualifier = *fmt;
189 ++fmt;
190 }
191
192 /* default base */
193 base = 10;
194
195 switch (*fmt) {
196 case 'c':
197 if (!(flags & LEFT))
198 while (--field_width > 0)
199 *str++ = ' ';
200 *str++ = (unsigned char)va_arg(args, int);
201 while (--field_width > 0)
202 *str++ = ' ';
203 continue;
204
205 case 's':
206 s = va_arg(args, char *);
207 len = strnlen(s, precision);
208
209 if (!(flags & LEFT))
210 while (len < field_width--)
211 *str++ = ' ';
212 for (i = 0; i < len; ++i)
213 *str++ = *s++;
214 while (len < field_width--)
215 *str++ = ' ';
216 continue;
217
218 case 'p':
219 if (field_width == -1) {
220 field_width = 2 * sizeof(void *);
221 flags |= ZEROPAD;
222 }
223 str = number(str,
224 (unsigned long)va_arg(args, void *), 16,
225 field_width, precision, flags);
226 continue;
227
228 case 'n':
229 if (qualifier == 'l') {
230 long *ip = va_arg(args, long *);
231 *ip = (str - buf);
232 } else {
233 int *ip = va_arg(args, int *);
234 *ip = (str - buf);
235 }
236 continue;
237
238 case '%':
239 *str++ = '%';
240 continue;
241
242 /* integer number formats - set up the flags and "break" */
243 case 'o':
244 base = 8;
245 break;
246
247 case 'X':
248 flags |= LARGE;
249 case 'x':
250 base = 16;
251 break;
252
253 case 'd':
254 case 'i':
255 flags |= SIGN;
256 case 'u':
257 break;
258
259 default:
260 *str++ = '%';
261 if (*fmt)
262 *str++ = *fmt;
263 else
264 --fmt;
265 continue;
266 }
267 if (qualifier == 'l')
268 num = va_arg(args, unsigned long);
269 else if (qualifier == 'h') {
270 num = (unsigned short)va_arg(args, int);
271 if (flags & SIGN)
272 num = (short)num;
273 } else if (flags & SIGN)
274 num = va_arg(args, int);
275 else
276 num = va_arg(args, unsigned int);
277 str = number(str, num, base, field_width, precision, flags);
278 }
279 *str = '\0';
280 return str - buf;
281}
282
283int sprintf(char *buf, const char *fmt, ...)
284{
285 va_list args;
286 int i;
287
288 va_start(args, fmt);
289 i = vsprintf(buf, fmt, args);
290 va_end(args);
291 return i;
292}
293
294int printf(const char *fmt, ...)
295{
296 char printf_buf[1024];
297 va_list args;
298 int printed;
299
300 va_start(args, fmt);
301 printed = vsprintf(printf_buf, fmt, args);
302 va_end(args);
303
304 puts(printf_buf);
305
306 return printed;
307}
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
deleted file mode 100644
index 6dbcc95b2120..000000000000
--- a/arch/i386/boot/setup.S
+++ /dev/null
@@ -1,1075 +0,0 @@
1/*
2 * setup.S Copyright (C) 1991, 1992 Linus Torvalds
3 *
4 * setup.s is responsible for getting the system data from the BIOS,
5 * and putting them into the appropriate places in system memory.
6 * both setup.s and system has been loaded by the bootblock.
7 *
8 * This code asks the bios for memory/disk/other parameters, and
9 * puts them in a "safe" place: 0x90000-0x901FF, ie where the
10 * boot-block used to be. It is then up to the protected mode
11 * system to read them from there before the area is overwritten
12 * for buffer-blocks.
13 *
14 * Move PS/2 aux init code to psaux.c
15 * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
16 *
17 * some changes and additional features by Christoph Niemann,
18 * March 1993/June 1994 (Christoph.Niemann@linux.org)
19 *
20 * add APM BIOS checking by Stephen Rothwell, May 1994
21 * (sfr@canb.auug.org.au)
22 *
23 * High load stuff, initrd support and position independency
24 * by Hans Lermen & Werner Almesberger, February 1996
25 * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
26 *
27 * Video handling moved to video.S by Martin Mares, March 1996
28 * <mj@k332.feld.cvut.cz>
29 *
30 * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
31 * parsons) to avoid loadlin confusion, July 1997
32 *
33 * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
34 * <stiker@northlink.com>
35 *
36 * Fix to work around buggy BIOSes which don't use carry bit correctly
37 * and/or report extended memory in CX/DX for e801h memory size detection
38 * call. As a result the kernel got wrong figures. The int15/e801h docs
39 * from Ralf Brown interrupt list seem to indicate AX/BX should be used
40 * anyway. So to avoid breaking many machines (presumably there was a reason
41 * to orginally use CX/DX instead of AX/BX), we do a kludge to see
42 * if CX/DX have been changed in the e801 call and if so use AX/BX .
43 * Michael Miller, April 2001 <michaelm@mjmm.org>
44 *
45 * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
46 * by Robert Schwebel, December 2001 <robert@schwebel.de>
47 */
48
49#include <asm/segment.h>
50#include <linux/utsrelease.h>
51#include <linux/compile.h>
52#include <asm/boot.h>
53#include <asm/e820.h>
54#include <asm/page.h>
55#include <asm/setup.h>
56
57/* Signature words to ensure LILO loaded us right */
58#define SIG1 0xAA55
59#define SIG2 0x5A5A
60
61INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way
62SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536).
63SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment
64 # ... and the former contents of CS
65
66DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020
67
68.code16
69.globl begtext, begdata, begbss, endtext, enddata, endbss
70
71.text
72begtext:
73.data
74begdata:
75.bss
76begbss:
77.text
78
79start:
80 jmp trampoline
81
82# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
83
84 .ascii "HdrS" # header signature
85 .word 0x0206 # header version number (>= 0x0105)
86 # or else old loadlin-1.5 will fail)
87realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
88start_sys_seg: .word SYSSEG
89 .word kernel_version # pointing to kernel version string
90 # above section of header is compatible
91 # with loadlin-1.5 (header v1.5). Don't
92 # change it.
93
94type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
95 # Bootlin, SYSLX, bootsect...)
96 # See Documentation/i386/boot.txt for
97 # assigned ids
98
99# flags, unused bits must be zero (RFU) bit within loadflags
100loadflags:
101LOADED_HIGH = 1 # If set, the kernel is loaded high
102CAN_USE_HEAP = 0x80 # If set, the loader also has set
103 # heap_end_ptr to tell how much
104 # space behind setup.S can be used for
105 # heap purposes.
106 # Only the loader knows what is free
107#ifndef __BIG_KERNEL__
108 .byte 0
109#else
110 .byte LOADED_HIGH
111#endif
112
113setup_move_size: .word 0x8000 # size to move, when setup is not
114 # loaded at 0x90000. We will move setup
115 # to 0x90000 then just before jumping
116 # into the kernel. However, only the
117 # loader knows how much data behind
118 # us also needs to be loaded.
119
120code32_start: # here loaders can put a different
121 # start address for 32-bit code.
122#ifndef __BIG_KERNEL__
123 .long 0x1000 # 0x1000 = default for zImage
124#else
125 .long 0x100000 # 0x100000 = default for big kernel
126#endif
127
128ramdisk_image: .long 0 # address of loaded ramdisk image
129 # Here the loader puts the 32-bit
130 # address where it loaded the image.
131 # This only will be read by the kernel.
132
133ramdisk_size: .long 0 # its size in bytes
134
135bootsect_kludge:
136 .long 0 # obsolete
137
138heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later)
139 # space from here (exclusive) down to
140 # end of setup code can be used by setup
141 # for local heap purposes.
142
143pad1: .word 0
144cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
145 # If nonzero, a 32-bit pointer
146 # to the kernel command line.
147 # The command line should be
148 # located between the start of
149 # setup and the end of low
150 # memory (0xa0000), or it may
151 # get overwritten before it
152 # gets read. If this field is
153 # used, there is no longer
154 # anything magical about the
155 # 0x90000 segment; the setup
156 # can be located anywhere in
157 # low memory 0x10000 or higher.
158
159ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
160 # (Header version 0x0203 or later)
161 # The highest safe address for
162 # the contents of an initrd
163
164kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment
165 #required for protected mode
166 #kernel
167#ifdef CONFIG_RELOCATABLE
168relocatable_kernel: .byte 1
169#else
170relocatable_kernel: .byte 0
171#endif
172pad2: .byte 0
173pad3: .word 0
174
175cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
176 #added with boot protocol
177 #version 2.06
178
179trampoline: call start_of_setup
180 .align 16
181 # The offset at this point is 0x240
182 .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
183# End of setup header #####################################################
184
185start_of_setup:
186# Bootlin depends on this being done early
187 movw $0x01500, %ax
188 movb $0x81, %dl
189 int $0x13
190
191#ifdef SAFE_RESET_DISK_CONTROLLER
192# Reset the disk controller.
193 movw $0x0000, %ax
194 movb $0x80, %dl
195 int $0x13
196#endif
197
198# Set %ds = %cs, we know that SETUPSEG = %cs at this point
199 movw %cs, %ax # aka SETUPSEG
200 movw %ax, %ds
201# Check signature at end of setup
202 cmpw $SIG1, setup_sig1
203 jne bad_sig
204
205 cmpw $SIG2, setup_sig2
206 jne bad_sig
207
208 jmp good_sig1
209
210# Routine to print asciiz string at ds:si
211prtstr:
212 lodsb
213 andb %al, %al
214 jz fin
215
216 call prtchr
217 jmp prtstr
218
219fin: ret
220
221# Space printing
222prtsp2: call prtspc # Print double space
223prtspc: movb $0x20, %al # Print single space (note: fall-thru)
224
225# Part of above routine, this one just prints ascii al
226prtchr: pushw %ax
227 pushw %cx
228 movw $7,%bx
229 movw $0x01, %cx
230 movb $0x0e, %ah
231 int $0x10
232 popw %cx
233 popw %ax
234 ret
235
236beep: movb $0x07, %al
237 jmp prtchr
238
239no_sig_mess: .string "No setup signature found ..."
240
241good_sig1:
242 jmp good_sig
243
244# We now have to find the rest of the setup code/data
245bad_sig:
246 movw %cs, %ax # SETUPSEG
247 subw $DELTA_INITSEG, %ax # INITSEG
248 movw %ax, %ds
249 xorb %bh, %bh
250 movb (497), %bl # get setup sect from bootsect
251 subw $4, %bx # LILO loads 4 sectors of setup
252 shlw $8, %bx # convert to words (1sect=2^8 words)
253 movw %bx, %cx
254 shrw $3, %bx # convert to segment
255 addw $SYSSEG, %bx
256 movw %bx, %cs:start_sys_seg
257# Move rest of setup code/data to here
258 movw $2048, %di # four sectors loaded by LILO
259 subw %si, %si
260 pushw %cs
261 popw %es
262 movw $SYSSEG, %ax
263 movw %ax, %ds
264 rep
265 movsw
266 movw %cs, %ax # aka SETUPSEG
267 movw %ax, %ds
268 cmpw $SIG1, setup_sig1
269 jne no_sig
270
271 cmpw $SIG2, setup_sig2
272 jne no_sig
273
274 jmp good_sig
275
276no_sig:
277 lea no_sig_mess, %si
278 call prtstr
279
280no_sig_loop:
281 hlt
282 jmp no_sig_loop
283
284good_sig:
285 movw %cs, %ax # aka SETUPSEG
286 subw $DELTA_INITSEG, %ax # aka INITSEG
287 movw %ax, %ds
288# Check if an old loader tries to load a big-kernel
289 testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel?
290 jz loader_ok # No, no danger for old loaders.
291
292 cmpb $0, %cs:type_of_loader # Do we have a loader that
293 # can deal with us?
294 jnz loader_ok # Yes, continue.
295
296 pushw %cs # No, we have an old loader,
297 popw %ds # die.
298 lea loader_panic_mess, %si
299 call prtstr
300
301 jmp no_sig_loop
302
303loader_panic_mess: .string "Wrong loader, giving up..."
304
305# check minimum cpuid
306# we do this here because it is the last place we can actually
307# show a user visible error message. Later the video modus
308# might be already messed up.
309loader_ok:
310 call verify_cpu
311 testl %eax,%eax
312 jz cpu_ok
313 movw %cs,%ax # aka SETUPSEG
314 movw %ax,%ds
315 lea cpu_panic_mess,%si
316 call prtstr
3171: jmp 1b
318
319cpu_panic_mess:
320 .asciz "PANIC: CPU too old for this kernel."
321
322#include "../kernel/verify_cpu.S"
323
324cpu_ok:
325# Get memory size (extended mem, kB)
326
327 xorl %eax, %eax
328 movl %eax, (0x1e0)
329#ifndef STANDARD_MEMORY_BIOS_CALL
330 movb %al, (E820NR)
331# Try three different memory detection schemes. First, try
332# e820h, which lets us assemble a memory map, then try e801h,
333# which returns a 32-bit memory size, and finally 88h, which
334# returns 0-64m
335
336# method E820H:
337# the memory map from hell. e820h returns memory classified into
338# a whole bunch of different types, and allows memory holes and
339# everything. We scan through this memory map and build a list
340# of the first 32 memory areas, which we return at [E820MAP].
341# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
342
343#define SMAP 0x534d4150
344
345meme820:
346 xorl %ebx, %ebx # continuation counter
347 movw $E820MAP, %di # point into the whitelist
348 # so we can have the bios
349 # directly write into it.
350
351jmpe820:
352 movl $0x0000e820, %eax # e820, upper word zeroed
353 movl $SMAP, %edx # ascii 'SMAP'
354 movl $20, %ecx # size of the e820rec
355 pushw %ds # data record.
356 popw %es
357 int $0x15 # make the call
358 jc bail820 # fall to e801 if it fails
359
360 cmpl $SMAP, %eax # check the return is `SMAP'
361 jne bail820 # fall to e801 if it fails
362
363# cmpl $1, 16(%di) # is this usable memory?
364# jne again820
365
366 # If this is usable memory, we save it by simply advancing %di by
367 # sizeof(e820rec).
368 #
369good820:
370 movb (E820NR), %al # up to 128 entries
371 cmpb $E820MAX, %al
372 jae bail820
373
374 incb (E820NR)
375 movw %di, %ax
376 addw $20, %ax
377 movw %ax, %di
378again820:
379 cmpl $0, %ebx # check to see if
380 jne jmpe820 # %ebx is set to EOF
381bail820:
382
383
384# method E801H:
385# memory size is in 1k chunksizes, to avoid confusing loadlin.
386# we store the 0xe801 memory size in a completely different place,
387# because it will most likely be longer than 16 bits.
388# (use 1e0 because that's what Larry Augustine uses in his
389# alternative new memory detection scheme, and it's sensible
390# to write everything into the same place.)
391
392meme801:
393 stc # fix to work around buggy
394 xorw %cx,%cx # BIOSes which don't clear/set
395 xorw %dx,%dx # carry on pass/error of
396 # e801h memory size call
397 # or merely pass cx,dx though
398 # without changing them.
399 movw $0xe801, %ax
400 int $0x15
401 jc mem88
402
403 cmpw $0x0, %cx # Kludge to handle BIOSes
404 jne e801usecxdx # which report their extended
405 cmpw $0x0, %dx # memory in AX/BX rather than
406 jne e801usecxdx # CX/DX. The spec I have read
407 movw %ax, %cx # seems to indicate AX/BX
408 movw %bx, %dx # are more reasonable anyway...
409
410e801usecxdx:
411 andl $0xffff, %edx # clear sign extend
412 shll $6, %edx # and go from 64k to 1k chunks
413 movl %edx, (0x1e0) # store extended memory size
414 andl $0xffff, %ecx # clear sign extend
415 addl %ecx, (0x1e0) # and add lower memory into
416 # total size.
417
418# Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
419# 64mb, depending on the bios) in ax.
420mem88:
421
422#endif
423 movb $0x88, %ah
424 int $0x15
425 movw %ax, (2)
426
427# Set the keyboard repeat rate to the max
428 movw $0x0305, %ax
429 xorw %bx, %bx
430 int $0x16
431
432# Check for video adapter and its parameters and allow the
433# user to browse video modes.
434 call video # NOTE: we need %ds pointing
435 # to bootsector
436
437# Get hd0 data...
438 xorw %ax, %ax
439 movw %ax, %ds
440 ldsw (4 * 0x41), %si
441 movw %cs, %ax # aka SETUPSEG
442 subw $DELTA_INITSEG, %ax # aka INITSEG
443 pushw %ax
444 movw %ax, %es
445 movw $0x0080, %di
446 movw $0x10, %cx
447 pushw %cx
448 cld
449 rep
450 movsb
451# Get hd1 data...
452 xorw %ax, %ax
453 movw %ax, %ds
454 ldsw (4 * 0x46), %si
455 popw %cx
456 popw %es
457 movw $0x0090, %di
458 rep
459 movsb
460# Check that there IS a hd1 :-)
461 movw $0x01500, %ax
462 movb $0x81, %dl
463 int $0x13
464 jc no_disk1
465
466 cmpb $3, %ah
467 je is_disk1
468
469no_disk1:
470 movw %cs, %ax # aka SETUPSEG
471 subw $DELTA_INITSEG, %ax # aka INITSEG
472 movw %ax, %es
473 movw $0x0090, %di
474 movw $0x10, %cx
475 xorw %ax, %ax
476 cld
477 rep
478 stosb
479is_disk1:
480# check for Micro Channel (MCA) bus
481 movw %cs, %ax # aka SETUPSEG
482 subw $DELTA_INITSEG, %ax # aka INITSEG
483 movw %ax, %ds
484 xorw %ax, %ax
485 movw %ax, (0xa0) # set table length to 0
486 movb $0xc0, %ah
487 stc
488 int $0x15 # moves feature table to es:bx
489 jc no_mca
490
491 pushw %ds
492 movw %es, %ax
493 movw %ax, %ds
494 movw %cs, %ax # aka SETUPSEG
495 subw $DELTA_INITSEG, %ax # aka INITSEG
496 movw %ax, %es
497 movw %bx, %si
498 movw $0xa0, %di
499 movw (%si), %cx
500 addw $2, %cx # table length is a short
501 cmpw $0x10, %cx
502 jc sysdesc_ok
503
504 movw $0x10, %cx # we keep only first 16 bytes
505sysdesc_ok:
506 rep
507 movsb
508 popw %ds
509no_mca:
510#ifdef CONFIG_X86_VOYAGER
511 movb $0xff, 0x40 # flag on config found
512 movb $0xc0, %al
513 mov $0xff, %ah
514 int $0x15 # put voyager config info at es:di
515 jc no_voyager
516 movw $0x40, %si # place voyager info in apm table
517 cld
518 movw $7, %cx
519voyager_rep:
520 movb %es:(%di), %al
521 movb %al,(%si)
522 incw %di
523 incw %si
524 decw %cx
525 jnz voyager_rep
526no_voyager:
527#endif
528# Check for PS/2 pointing device
529 movw %cs, %ax # aka SETUPSEG
530 subw $DELTA_INITSEG, %ax # aka INITSEG
531 movw %ax, %ds
532 movb $0, (0x1ff) # default is no pointing device
533 int $0x11 # int 0x11: equipment list
534 testb $0x04, %al # check if mouse installed
535 jz no_psmouse
536
537 movb $0xAA, (0x1ff) # device present
538no_psmouse:
539
540#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
541 movl $0x0000E980, %eax # IST Support
542 movl $0x47534943, %edx # Request value
543 int $0x15
544
545 movl %eax, (96)
546 movl %ebx, (100)
547 movl %ecx, (104)
548 movl %edx, (108)
549#endif
550
551#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
552# Then check for an APM BIOS...
553 # %ds points to the bootsector
554 movw $0, 0x40 # version = 0 means no APM BIOS
555 movw $0x05300, %ax # APM BIOS installation check
556 xorw %bx, %bx
557 int $0x15
558 jc done_apm_bios # Nope, no APM BIOS
559
560 cmpw $0x0504d, %bx # Check for "PM" signature
561 jne done_apm_bios # No signature, no APM BIOS
562
563 andw $0x02, %cx # Is 32 bit supported?
564 je done_apm_bios # No 32-bit, no (good) APM BIOS
565
566 movw $0x05304, %ax # Disconnect first just in case
567 xorw %bx, %bx
568 int $0x15 # ignore return code
569 movw $0x05303, %ax # 32 bit connect
570 xorl %ebx, %ebx
571 xorw %cx, %cx # paranoia :-)
572 xorw %dx, %dx # ...
573 xorl %esi, %esi # ...
574 xorw %di, %di # ...
575 int $0x15
576 jc no_32_apm_bios # Ack, error.
577
578 movw %ax, (66) # BIOS code segment
579 movl %ebx, (68) # BIOS entry point offset
580 movw %cx, (72) # BIOS 16 bit code segment
581 movw %dx, (74) # BIOS data segment
582 movl %esi, (78) # BIOS code segment lengths
583 movw %di, (82) # BIOS data segment length
584# Redo the installation check as the 32 bit connect
585# modifies the flags returned on some BIOSs
586 movw $0x05300, %ax # APM BIOS installation check
587 xorw %bx, %bx
588 xorw %cx, %cx # paranoia
589 int $0x15
590 jc apm_disconnect # error -> shouldn't happen
591
592 cmpw $0x0504d, %bx # check for "PM" signature
593 jne apm_disconnect # no sig -> shouldn't happen
594
595 movw %ax, (64) # record the APM BIOS version
596 movw %cx, (76) # and flags
597 jmp done_apm_bios
598
599apm_disconnect: # Tidy up
600 movw $0x05304, %ax # Disconnect
601 xorw %bx, %bx
602 int $0x15 # ignore return code
603
604 jmp done_apm_bios
605
606no_32_apm_bios:
607 andw $0xfffd, (76) # remove 32 bit support bit
608done_apm_bios:
609#endif
610
611#include "edd.S"
612
613# Now we want to move to protected mode ...
614 cmpw $0, %cs:realmode_swtch
615 jz rmodeswtch_normal
616
617 lcall *%cs:realmode_swtch
618
619 jmp rmodeswtch_end
620
621rmodeswtch_normal:
622 pushw %cs
623 call default_switch
624
625rmodeswtch_end:
626# Now we move the system to its rightful place ... but we check if we have a
627# big-kernel. In that case we *must* not move it ...
628 testb $LOADED_HIGH, %cs:loadflags
629 jz do_move0 # .. then we have a normal low
630 # loaded zImage
631 # .. or else we have a high
632 # loaded bzImage
633 jmp end_move # ... and we skip moving
634
635do_move0:
636 movw $0x100, %ax # start of destination segment
637 movw %cs, %bp # aka SETUPSEG
638 subw $DELTA_INITSEG, %bp # aka INITSEG
639 movw %cs:start_sys_seg, %bx # start of source segment
640 cld
641do_move:
642 movw %ax, %es # destination segment
643 incb %ah # instead of add ax,#0x100
644 movw %bx, %ds # source segment
645 addw $0x100, %bx
646 subw %di, %di
647 subw %si, %si
648 movw $0x800, %cx
649 rep
650 movsw
651 cmpw %bp, %bx # assume start_sys_seg > 0x200,
652 # so we will perhaps read one
653 # page more than needed, but
654 # never overwrite INITSEG
655 # because destination is a
656 # minimum one page below source
657 jb do_move
658
659end_move:
660# then we load the segment descriptors
661 movw %cs, %ax # aka SETUPSEG
662 movw %ax, %ds
663
664# Check whether we need to be downward compatible with version <=201
665 cmpl $0, cmd_line_ptr
666 jne end_move_self # loader uses version >=202 features
667 cmpb $0x20, type_of_loader
668 je end_move_self # bootsect loader, we know of it
669
670# Boot loader doesnt support boot protocol version 2.02.
671# If we have our code not at 0x90000, we need to move it there now.
672# We also then need to move the params behind it (commandline)
673# Because we would overwrite the code on the current IP, we move
674# it in two steps, jumping high after the first one.
675 movw %cs, %ax
676 cmpw $SETUPSEG, %ax
677 je end_move_self
678
679 cli # make sure we really have
680 # interrupts disabled !
681 # because after this the stack
682 # should not be used
683 subw $DELTA_INITSEG, %ax # aka INITSEG
684 movw %ss, %dx
685 cmpw %ax, %dx
686 jb move_self_1
687
688 addw $INITSEG, %dx
689 subw %ax, %dx # this will go into %ss after
690 # the move
691move_self_1:
692 movw %ax, %ds
693 movw $INITSEG, %ax # real INITSEG
694 movw %ax, %es
695 movw %cs:setup_move_size, %cx
696 std # we have to move up, so we use
697 # direction down because the
698 # areas may overlap
699 movw %cx, %di
700 decw %di
701 movw %di, %si
702 subw $move_self_here+0x200, %cx
703 rep
704 movsb
705 ljmp $SETUPSEG, $move_self_here
706
707move_self_here:
708 movw $move_self_here+0x200, %cx
709 rep
710 movsb
711 movw $SETUPSEG, %ax
712 movw %ax, %ds
713 movw %dx, %ss
714end_move_self: # now we are at the right place
715
716#
717# Enable A20. This is at the very best an annoying procedure.
718# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
719# AMD Elan bug fix by Robert Schwebel.
720#
721
722#if defined(CONFIG_X86_ELAN)
723 movb $0x02, %al # alternate A20 gate
724 outb %al, $0x92 # this works on SC410/SC520
725a20_elan_wait:
726 call a20_test
727 jz a20_elan_wait
728 jmp a20_done
729#endif
730
731
732A20_TEST_LOOPS = 32 # Iterations per wait
733A20_ENABLE_LOOPS = 255 # Total loops to try
734
735
736#ifndef CONFIG_X86_VOYAGER
737a20_try_loop:
738
739 # First, see if we are on a system with no A20 gate.
740a20_none:
741 call a20_test
742 jnz a20_done
743
744 # Next, try the BIOS (INT 0x15, AX=0x2401)
745a20_bios:
746 movw $0x2401, %ax
747 pushfl # Be paranoid about flags
748 int $0x15
749 popfl
750
751 call a20_test
752 jnz a20_done
753
754 # Try enabling A20 through the keyboard controller
755#endif /* CONFIG_X86_VOYAGER */
756a20_kbc:
757 call empty_8042
758
759#ifndef CONFIG_X86_VOYAGER
760 call a20_test # Just in case the BIOS worked
761 jnz a20_done # but had a delayed reaction.
762#endif
763
764 movb $0xD1, %al # command write
765 outb %al, $0x64
766 call empty_8042
767
768 movb $0xDF, %al # A20 on
769 outb %al, $0x60
770 call empty_8042
771
772#ifndef CONFIG_X86_VOYAGER
773 # Wait until a20 really *is* enabled; it can take a fair amount of
774 # time on certain systems; Toshiba Tecras are known to have this
775 # problem.
776a20_kbc_wait:
777 xorw %cx, %cx
778a20_kbc_wait_loop:
779 call a20_test
780 jnz a20_done
781 loop a20_kbc_wait_loop
782
783 # Final attempt: use "configuration port A"
784a20_fast:
785 inb $0x92, %al # Configuration Port A
786 orb $0x02, %al # "fast A20" version
787 andb $0xFE, %al # don't accidentally reset
788 outb %al, $0x92
789
790 # Wait for configuration port A to take effect
791a20_fast_wait:
792 xorw %cx, %cx
793a20_fast_wait_loop:
794 call a20_test
795 jnz a20_done
796 loop a20_fast_wait_loop
797
798 # A20 is still not responding. Try frobbing it again.
799 #
800 decb (a20_tries)
801 jnz a20_try_loop
802
803 movw $a20_err_msg, %si
804 call prtstr
805
806a20_die:
807 hlt
808 jmp a20_die
809
810a20_tries:
811 .byte A20_ENABLE_LOOPS
812
813a20_err_msg:
814 .ascii "linux: fatal error: A20 gate not responding!"
815 .byte 13, 10, 0
816
817 # If we get here, all is good
818a20_done:
819
820#endif /* CONFIG_X86_VOYAGER */
821# set up gdt and idt and 32bit start address
822 lidt idt_48 # load idt with 0,0
823 xorl %eax, %eax # Compute gdt_base
824 movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
825 shll $4, %eax
826 addl %eax, code32
827 addl $gdt, %eax
828 movl %eax, (gdt_48+2)
829 lgdt gdt_48 # load gdt with whatever is
830 # appropriate
831
832# make sure any possible coprocessor is properly reset..
833 xorw %ax, %ax
834 outb %al, $0xf0
835 call delay
836
837 outb %al, $0xf1
838 call delay
839
840# well, that went ok, I hope. Now we mask all interrupts - the rest
841# is done in init_IRQ().
842 movb $0xFF, %al # mask all interrupts for now
843 outb %al, $0xA1
844 call delay
845
846 movb $0xFB, %al # mask all irq's but irq2 which
847 outb %al, $0x21 # is cascaded
848
849# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
850# need no steenking BIOS anyway (except for the initial loading :-).
851# The BIOS-routine wants lots of unnecessary data, and it's less
852# "interesting" anyway. This is how REAL programmers do it.
853#
854# Well, now's the time to actually move into protected mode. To make
855# things as simple as possible, we do no register set-up or anything,
856# we let the gnu-compiled 32-bit programs do that. We just jump to
857# absolute address 0x1000 (or the loader supplied one),
858# in 32-bit protected mode.
859#
860# Note that the short jump isn't strictly needed, although there are
861# reasons why it might be a good idea. It won't hurt in any case.
862 movw $1, %ax # protected mode (PE) bit
863 lmsw %ax # This is it!
864 jmp flush_instr
865
866flush_instr:
867 xorw %bx, %bx # Flag to indicate a boot
868 xorl %esi, %esi # Pointer to real-mode code
869 movw %cs, %si
870 subw $DELTA_INITSEG, %si
871 shll $4, %esi # Convert to 32-bit pointer
872
873# jump to startup_32 in arch/i386/boot/compressed/head.S
874#
875# NOTE: For high loaded big kernels we need a
876# jmpi 0x100000,__BOOT_CS
877#
878# but we yet haven't reloaded the CS register, so the default size
879# of the target offset still is 16 bit.
880# However, using an operand prefix (0x66), the CPU will properly
881# take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
882# Manual, Mixing 16-bit and 32-bit code, page 16-6)
883
884 .byte 0x66, 0xea # prefix + jmpi-opcode
885code32: .long startup_32 # will be set to %cs+startup_32
886 .word __BOOT_CS
887.code32
888startup_32:
889 movl $(__BOOT_DS), %eax
890 movl %eax, %ds
891 movl %eax, %es
892 movl %eax, %fs
893 movl %eax, %gs
894 movl %eax, %ss
895
896 xorl %eax, %eax
8971: incl %eax # check that A20 really IS enabled
898 movl %eax, 0x00000000 # loop forever if it isn't
899 cmpl %eax, 0x00100000
900 je 1b
901
902 # Jump to the 32bit entry point
903 jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
904.code16
905
906# Here's a bunch of information about your current kernel..
907kernel_version: .ascii UTS_RELEASE
908 .ascii " ("
909 .ascii LINUX_COMPILE_BY
910 .ascii "@"
911 .ascii LINUX_COMPILE_HOST
912 .ascii ") "
913 .ascii UTS_VERSION
914 .byte 0
915
916# This is the default real mode switch routine.
917# to be called just before protected mode transition
918default_switch:
919 cli # no interrupts allowed !
920 movb $0x80, %al # disable NMI for bootup
921 # sequence
922 outb %al, $0x70
923 lret
924
925
926#ifndef CONFIG_X86_VOYAGER
927# This routine tests whether or not A20 is enabled. If so, it
928# exits with zf = 0.
929#
930# The memory address used, 0x200, is the int $0x80 vector, which
931# should be safe.
932
933A20_TEST_ADDR = 4*0x80
934
935a20_test:
936 pushw %cx
937 pushw %ax
938 xorw %cx, %cx
939 movw %cx, %fs # Low memory
940 decw %cx
941 movw %cx, %gs # High memory area
942 movw $A20_TEST_LOOPS, %cx
943 movw %fs:(A20_TEST_ADDR), %ax
944 pushw %ax
945a20_test_wait:
946 incw %ax
947 movw %ax, %fs:(A20_TEST_ADDR)
948 call delay # Serialize and make delay constant
949 cmpw %gs:(A20_TEST_ADDR+0x10), %ax
950 loope a20_test_wait
951
952 popw %fs:(A20_TEST_ADDR)
953 popw %ax
954 popw %cx
955 ret
956
957#endif /* CONFIG_X86_VOYAGER */
958
959# This routine checks that the keyboard command queue is empty
960# (after emptying the output buffers)
961#
962# Some machines have delusions that the keyboard buffer is always full
963# with no keyboard attached...
964#
965# If there is no keyboard controller, we will usually get 0xff
966# to all the reads. With each IO taking a microsecond and
967# a timeout of 100,000 iterations, this can take about half a
968# second ("delay" == outb to port 0x80). That should be ok,
969# and should also be plenty of time for a real keyboard controller
970# to empty.
971#
972
973empty_8042:
974 pushl %ecx
975 movl $100000, %ecx
976
977empty_8042_loop:
978 decl %ecx
979 jz empty_8042_end_loop
980
981 call delay
982
983 inb $0x64, %al # 8042 status port
984 testb $1, %al # output buffer?
985 jz no_output
986
987 call delay
988 inb $0x60, %al # read it
989 jmp empty_8042_loop
990
991no_output:
992 testb $2, %al # is input buffer full?
993 jnz empty_8042_loop # yes - loop
994empty_8042_end_loop:
995 popl %ecx
996 ret
997
998# Read the cmos clock. Return the seconds in al
999gettime:
1000 pushw %cx
1001 movb $0x02, %ah
1002 int $0x1a
1003 movb %dh, %al # %dh contains the seconds
1004 andb $0x0f, %al
1005 movb %dh, %ah
1006 movb $0x04, %cl
1007 shrb %cl, %ah
1008 aad
1009 popw %cx
1010 ret
1011
1012# Delay is needed after doing I/O
1013delay:
1014 outb %al,$0x80
1015 ret
1016
1017# Descriptor tables
1018#
1019# NOTE: The intel manual says gdt should be sixteen bytes aligned for
1020# efficiency reasons. However, there are machines which are known not
1021# to boot with misaligned GDTs, so alter this at your peril! If you alter
1022# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
1023# empty GDT entries (one for NULL and one reserved).
1024#
1025# NOTE: On some CPUs, the GDT must be 8 byte aligned. This is
1026# true for the Voyager Quad CPU card which will not boot without
1027# This directive. 16 byte aligment is recommended by intel.
1028#
1029 .align 16
1030gdt:
1031 .fill GDT_ENTRY_BOOT_CS,8,0
1032
1033 .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
1034 .word 0 # base address = 0
1035 .word 0x9A00 # code read/exec
1036 .word 0x00CF # granularity = 4096, 386
1037 # (+5th nibble of limit)
1038
1039 .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
1040 .word 0 # base address = 0
1041 .word 0x9200 # data read/write
1042 .word 0x00CF # granularity = 4096, 386
1043 # (+5th nibble of limit)
1044gdt_end:
1045 .align 4
1046
1047 .word 0 # alignment byte
1048idt_48:
1049 .word 0 # idt limit = 0
1050 .word 0, 0 # idt base = 0L
1051
1052 .word 0 # alignment byte
1053gdt_48:
1054 .word gdt_end - gdt - 1 # gdt limit
1055 .word 0, 0 # gdt base (filled in later)
1056
1057# Include video setup & detection code
1058
1059#include "video.S"
1060
1061# Setup signature -- must be last
1062setup_sig1: .word SIG1
1063setup_sig2: .word SIG2
1064
1065# After this point, there is some free space which is used by the video mode
1066# handling code to store the temporary mode table (not used by the kernel).
1067
1068modelist:
1069
1070.text
1071endtext:
1072.data
1073enddata:
1074.bss
1075endbss:
diff --git a/arch/i386/boot/setup.ld b/arch/i386/boot/setup.ld
new file mode 100644
index 000000000000..df9234b3a5e0
--- /dev/null
+++ b/arch/i386/boot/setup.ld
@@ -0,0 +1,54 @@
1/*
2 * setup.ld
3 *
4 * Linker script for the i386 setup code
5 */
6OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7OUTPUT_ARCH(i386)
8ENTRY(_start)
9
10SECTIONS
11{
12 . = 0;
13 .bstext : { *(.bstext) }
14 .bsdata : { *(.bsdata) }
15
16 . = 497;
17 .header : { *(.header) }
18 .inittext : { *(.inittext) }
19 .initdata : { *(.initdata) }
20 .text : { *(.text*) }
21
22 . = ALIGN(16);
23 .rodata : { *(.rodata*) }
24
25 .videocards : {
26 video_cards = .;
27 *(.videocards)
28 video_cards_end = .;
29 }
30
31 . = ALIGN(16);
32 .data : { *(.data*) }
33
34 .signature : {
35 setup_sig = .;
36 LONG(0x5a5aaa55)
37 }
38
39
40 . = ALIGN(16);
41 .bss :
42 {
43 __bss_start = .;
44 *(.bss)
45 __bss_end = .;
46 }
47 . = ALIGN(16);
48 _end = .;
49
50 /DISCARD/ : { *(.note*) }
51
52 . = ASSERT(_end <= 0x8000, "Setup too big!");
53 . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
54}
diff --git a/arch/i386/boot/string.c b/arch/i386/boot/string.c
new file mode 100644
index 000000000000..481a22097781
--- /dev/null
+++ b/arch/i386/boot/string.c
@@ -0,0 +1,52 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/string.c
13 *
14 * Very basic string functions
15 */
16
17#include "boot.h"
18
19int strcmp(const char *str1, const char *str2)
20{
21 const unsigned char *s1 = (const unsigned char *)str1;
22 const unsigned char *s2 = (const unsigned char *)str2;
23 int delta = 0;
24
25 while (*s1 || *s2) {
26 delta = *s2 - *s1;
27 if (delta)
28 return delta;
29 s1++;
30 s2++;
31 }
32 return 0;
33}
34
35size_t strnlen(const char *s, size_t maxlen)
36{
37 const char *es = s;
38 while (*es && maxlen) {
39 es++;
40 maxlen--;
41 }
42
43 return (es - s);
44}
45
46unsigned int atou(const char *s)
47{
48 unsigned int i = 0;
49 while (isdigit(*s))
50 i = i * 10 + (*s++ - '0');
51 return i;
52}
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
index 05798419a6a9..886f47d8a488 100644
--- a/arch/i386/boot/tools/build.c
+++ b/arch/i386/boot/tools/build.c
@@ -1,13 +1,12 @@
1/* 1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds 2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 1997 Martin Mares 3 * Copyright (C) 1997 Martin Mares
4 * Copyright (C) 2007 H. Peter Anvin
4 */ 5 */
5 6
6/* 7/*
7 * This file builds a disk-image from three different files: 8 * This file builds a disk-image from three different files:
8 * 9 *
9 * - bootsect: compatibility mbr which prints an error message if
10 * someone tries to boot the kernel directly.
11 * - setup: 8086 machine code, sets up system parm 10 * - setup: 8086 machine code, sets up system parm
12 * - system: 80386 code for actual system 11 * - system: 80386 code for actual system
13 * 12 *
@@ -21,6 +20,7 @@
21 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 20 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
22 * Cross compiling fixes by Gertjan van Wingerde, July 1996 21 * Cross compiling fixes by Gertjan van Wingerde, July 1996
23 * Rewritten by Martin Mares, April 1997 22 * Rewritten by Martin Mares, April 1997
23 * Substantially overhauled by H. Peter Anvin, April 2007
24 */ 24 */
25 25
26#include <stdio.h> 26#include <stdio.h>
@@ -32,23 +32,25 @@
32#include <sys/sysmacros.h> 32#include <sys/sysmacros.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <fcntl.h> 34#include <fcntl.h>
35#include <sys/mman.h>
35#include <asm/boot.h> 36#include <asm/boot.h>
36 37
37typedef unsigned char byte; 38typedef unsigned char u8;
38typedef unsigned short word; 39typedef unsigned short u16;
39typedef unsigned long u32; 40typedef unsigned long u32;
40 41
41#define DEFAULT_MAJOR_ROOT 0 42#define DEFAULT_MAJOR_ROOT 0
42#define DEFAULT_MINOR_ROOT 0 43#define DEFAULT_MINOR_ROOT 0
43 44
44/* Minimal number of setup sectors (see also bootsect.S) */ 45/* Minimal number of setup sectors */
45#define SETUP_SECTS 4 46#define SETUP_SECT_MIN 5
47#define SETUP_SECT_MAX 64
46 48
47byte buf[1024]; 49/* This must be large enough to hold the entire setup */
48int fd; 50u8 buf[SETUP_SECT_MAX*512];
49int is_big_kernel; 51int is_big_kernel;
50 52
51void die(const char * str, ...) 53static void die(const char * str, ...)
52{ 54{
53 va_list args; 55 va_list args;
54 va_start(args, str); 56 va_start(args, str);
@@ -57,15 +59,9 @@ void die(const char * str, ...)
57 exit(1); 59 exit(1);
58} 60}
59 61
60void file_open(const char *name) 62static void usage(void)
61{ 63{
62 if ((fd = open(name, O_RDONLY, 0)) < 0) 64 die("Usage: build [-b] setup system [rootdev] [> image]");
63 die("Unable to open `%s': %m", name);
64}
65
66void usage(void)
67{
68 die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
69} 65}
70 66
71int main(int argc, char ** argv) 67int main(int argc, char ** argv)
@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
73 unsigned int i, sz, setup_sectors; 69 unsigned int i, sz, setup_sectors;
74 int c; 70 int c;
75 u32 sys_size; 71 u32 sys_size;
76 byte major_root, minor_root; 72 u8 major_root, minor_root;
77 struct stat sb; 73 struct stat sb;
74 FILE *file;
75 int fd;
76 void *kernel;
78 77
79 if (argc > 2 && !strcmp(argv[1], "-b")) 78 if (argc > 2 && !strcmp(argv[1], "-b"))
80 { 79 {
81 is_big_kernel = 1; 80 is_big_kernel = 1;
82 argc--, argv++; 81 argc--, argv++;
83 } 82 }
84 if ((argc < 4) || (argc > 5)) 83 if ((argc < 3) || (argc > 4))
85 usage(); 84 usage();
86 if (argc > 4) { 85 if (argc > 3) {
87 if (!strcmp(argv[4], "CURRENT")) { 86 if (!strcmp(argv[3], "CURRENT")) {
88 if (stat("/", &sb)) { 87 if (stat("/", &sb)) {
89 perror("/"); 88 perror("/");
90 die("Couldn't stat /"); 89 die("Couldn't stat /");
91 } 90 }
92 major_root = major(sb.st_dev); 91 major_root = major(sb.st_dev);
93 minor_root = minor(sb.st_dev); 92 minor_root = minor(sb.st_dev);
94 } else if (strcmp(argv[4], "FLOPPY")) { 93 } else if (strcmp(argv[3], "FLOPPY")) {
95 if (stat(argv[4], &sb)) { 94 if (stat(argv[3], &sb)) {
96 perror(argv[4]); 95 perror(argv[3]);
97 die("Couldn't stat root device."); 96 die("Couldn't stat root device.");
98 } 97 }
99 major_root = major(sb.st_rdev); 98 major_root = major(sb.st_rdev);
@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
108 } 107 }
109 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); 108 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
110 109
111 file_open(argv[1]); 110 /* Copy the setup code */
112 i = read(fd, buf, sizeof(buf)); 111 file = fopen(argv[1], "r");
113 fprintf(stderr,"Boot sector %d bytes.\n",i); 112 if (!file)
114 if (i != 512) 113 die("Unable to open `%s': %m", argv[1]);
115 die("Boot block must be exactly 512 bytes"); 114 c = fread(buf, 1, sizeof(buf), file);
115 if (ferror(file))
116 die("read-error on `setup'");
117 if (c < 1024)
118 die("The setup must be at least 1024 bytes");
116 if (buf[510] != 0x55 || buf[511] != 0xaa) 119 if (buf[510] != 0x55 || buf[511] != 0xaa)
117 die("Boot block hasn't got boot flag (0xAA55)"); 120 die("Boot block hasn't got boot flag (0xAA55)");
121 fclose(file);
122
123 /* Pad unused space with zeros */
124 setup_sectors = (c + 511) / 512;
125 if (setup_sectors < SETUP_SECT_MIN)
126 setup_sectors = SETUP_SECT_MIN;
127 i = setup_sectors*512;
128 memset(buf+c, 0, i-c);
129
130 /* Set the default root device */
118 buf[508] = minor_root; 131 buf[508] = minor_root;
119 buf[509] = major_root; 132 buf[509] = major_root;
120 if (write(1, buf, 512) != 512)
121 die("Write call failed");
122 close (fd);
123
124 file_open(argv[2]); /* Copy the setup code */
125 for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
126 if (write(1, buf, c) != c)
127 die("Write call failed");
128 if (c != 0)
129 die("read-error on `setup'");
130 close (fd);
131
132 setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */
133 /* for compatibility with ancient versions of LILO. */
134 if (setup_sectors < SETUP_SECTS)
135 setup_sectors = SETUP_SECTS;
136 fprintf(stderr, "Setup is %d bytes.\n", i);
137 memset(buf, 0, sizeof(buf));
138 while (i < setup_sectors * 512) {
139 c = setup_sectors * 512 - i;
140 if (c > sizeof(buf))
141 c = sizeof(buf);
142 if (write(1, buf, c) != c)
143 die("Write call failed");
144 i += c;
145 }
146 133
147 file_open(argv[3]); 134 fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
148 if (fstat (fd, &sb)) 135
149 die("Unable to stat `%s': %m", argv[3]); 136 /* Open and stat the kernel file */
137 fd = open(argv[2], O_RDONLY);
138 if (fd < 0)
139 die("Unable to open `%s': %m", argv[2]);
140 if (fstat(fd, &sb))
141 die("Unable to stat `%s': %m", argv[2]);
150 sz = sb.st_size; 142 sz = sb.st_size;
151 fprintf (stderr, "System is %d kB\n", sz/1024); 143 fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
144 kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
145 if (kernel == MAP_FAILED)
146 die("Unable to mmap '%s': %m", argv[2]);
152 sys_size = (sz + 15) / 16; 147 sys_size = (sz + 15) / 16;
153 if (!is_big_kernel && sys_size > DEF_SYSSIZE) 148 if (!is_big_kernel && sys_size > DEF_SYSSIZE)
154 die("System is too big. Try using bzImage or modules."); 149 die("System is too big. Try using bzImage or modules.");
155 while (sz > 0) { 150
156 int l, n; 151 /* Patch the setup code with the appropriate size parameters */
157 152 buf[0x1f1] = setup_sectors-1;
158 l = (sz > sizeof(buf)) ? sizeof(buf) : sz; 153 buf[0x1f4] = sys_size;
159 if ((n=read(fd, buf, l)) != l) { 154 buf[0x1f5] = sys_size >> 8;
160 if (n < 0) 155 buf[0x1f6] = sys_size >> 16;
161 die("Error reading %s: %m", argv[3]); 156 buf[0x1f7] = sys_size >> 24;
162 else 157
163 die("%s: Unexpected EOF", argv[3]); 158 if (fwrite(buf, 1, i, stdout) != i)
164 } 159 die("Writing setup failed");
165 if (write(1, buf, l) != l) 160
166 die("Write failed"); 161 /* Copy the kernel code */
167 sz -= l; 162 if (fwrite(kernel, 1, sz, stdout) != sz)
168 } 163 die("Writing kernel failed");
169 close(fd); 164 close(fd);
170 165
171 if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */ 166 /* Everything is OK */
172 die("Output: seek failed"); 167 return 0;
173 buf[0] = setup_sectors;
174 if (write(1, buf, 1) != 1)
175 die("Write of setup sector count failed");
176 if (lseek(1, 500, SEEK_SET) != 500)
177 die("Output: seek failed");
178 buf[0] = (sys_size & 0xff);
179 buf[1] = ((sys_size >> 8) & 0xff);
180 buf[2] = ((sys_size >> 16) & 0xff);
181 buf[3] = ((sys_size >> 24) & 0xff);
182 if (write(1, buf, 4) != 4)
183 die("Write of image length failed");
184
185 return 0; /* Everything is OK */
186} 168}
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
new file mode 100644
index 000000000000..a8db78736b02
--- /dev/null
+++ b/arch/i386/boot/tty.c
@@ -0,0 +1,112 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/tty.c
13 *
14 * Very simple screen I/O
15 * XXX: Probably should add very simple serial I/O?
16 */
17
18#include "boot.h"
19
20/*
21 * These functions are in .inittext so they can be used to signal
22 * error during initialization.
23 */
24
25void __attribute__((section(".inittext"))) putchar(int ch)
26{
27 unsigned char c = ch;
28
29 if (c == '\n')
30 putchar('\r'); /* \n -> \r\n */
31
32 /* int $0x10 is known to have bugs involving touching registers
33 it shouldn't. Be extra conservative... */
34 asm volatile("pushal; int $0x10; popal"
35 : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
36}
37
38void __attribute__((section(".inittext"))) puts(const char *str)
39{
40 int n = 0;
41 while (*str) {
42 putchar(*str++);
43 n++;
44 }
45}
46
47/*
48 * Read the CMOS clock through the BIOS, and return the
49 * seconds in BCD.
50 */
51
52static u8 gettime(void)
53{
54 u16 ax = 0x0200;
55 u16 cx, dx;
56
57 asm("int $0x1a"
58 : "+a" (ax), "=c" (cx), "=d" (dx)
59 : : "ebx", "esi", "edi");
60
61 return dx >> 8;
62}
63
64/*
65 * Read from the keyboard
66 */
67int getchar(void)
68{
69 u16 ax = 0;
70 asm("int $0x16" : "+a" (ax));
71
72 return ax & 0xff;
73}
74
75static int kbd_pending(void)
76{
77 u8 pending;
78 asm("int $0x16; setnz %0"
79 : "=rm" (pending)
80 : "a" (0x0100));
81 return pending;
82}
83
84void kbd_flush(void)
85{
86 for (;;) {
87 if (!kbd_pending())
88 break;
89 getchar();
90 }
91}
92
93int getchar_timeout(void)
94{
95 int cnt = 30;
96 int t0, t1;
97
98 t0 = gettime();
99
100 while (cnt) {
101 if (kbd_pending())
102 return getchar();
103
104 t1 = gettime();
105 if (t0 != t1) {
106 cnt--;
107 t0 = t1;
108 }
109 }
110
111 return 0; /* Timeout! */
112}
diff --git a/arch/i386/boot/version.c b/arch/i386/boot/version.c
new file mode 100644
index 000000000000..c61462f7d9a7
--- /dev/null
+++ b/arch/i386/boot/version.c
@@ -0,0 +1,23 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/version.c
13 *
14 * Kernel version string
15 */
16
17#include "boot.h"
18#include <linux/utsrelease.h>
19#include <linux/compile.h>
20
21const char kernel_version[] =
22 UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
23 UTS_VERSION;
diff --git a/arch/i386/boot/vesa.h b/arch/i386/boot/vesa.h
new file mode 100644
index 000000000000..ff5b73cd406f
--- /dev/null
+++ b/arch/i386/boot/vesa.h
@@ -0,0 +1,79 @@
1/* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13#ifndef BOOT_VESA_H
14#define BOOT_VESA_H
15
16typedef struct {
17 u16 off, seg;
18} far_ptr;
19
20/* VESA General Information table */
21struct vesa_general_info {
22 u32 signature; /* 0 Magic number = "VESA" */
23 u16 version; /* 4 */
24 far_ptr vendor_string; /* 6 */
25 u32 capabilities; /* 10 */
26 far_ptr video_mode_ptr; /* 14 */
27 u16 total_memory; /* 18 */
28
29 u16 oem_software_rev; /* 20 */
30 far_ptr oem_vendor_name_ptr; /* 22 */
31 far_ptr oem_product_name_ptr; /* 26 */
32 far_ptr oem_product_rev_ptr; /* 30 */
33
34 u8 reserved[222]; /* 34 */
35 u8 oem_data[256]; /* 256 */
36} __attribute__ ((packed));
37
38#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
39#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
40
41struct vesa_mode_info {
42 u16 mode_attr; /* 0 */
43 u8 win_attr[2]; /* 2 */
44 u16 win_grain; /* 4 */
45 u16 win_size; /* 6 */
46 u16 win_seg[2]; /* 8 */
47 far_ptr win_scheme; /* 12 */
48 u16 logical_scan; /* 16 */
49
50 u16 h_res; /* 18 */
51 u16 v_res; /* 20 */
52 u8 char_width; /* 22 */
53 u8 char_height; /* 23 */
54 u8 memory_planes; /* 24 */
55 u8 bpp; /* 25 */
56 u8 banks; /* 26 */
57 u8 memory_layout; /* 27 */
58 u8 bank_size; /* 28 */
59 u8 image_planes; /* 29 */
60 u8 page_function; /* 30 */
61
62 u8 rmask; /* 31 */
63 u8 rpos; /* 32 */
64 u8 gmask; /* 33 */
65 u8 gpos; /* 34 */
66 u8 bmask; /* 35 */
67 u8 bpos; /* 36 */
68 u8 resv_mask; /* 37 */
69 u8 resv_pos; /* 38 */
70 u8 dcm_info; /* 39 */
71
72 u32 lfb_ptr; /* 40 Linear frame buffer address */
73 u32 offscreen_ptr; /* 44 Offscreen memory address */
74 u16 offscreen_size; /* 48 */
75
76 u8 reserved[206]; /* 50 */
77} __attribute__ ((packed));
78
79#endif /* LIB_SYS_VESA_H */
diff --git a/arch/i386/boot/video-bios.c b/arch/i386/boot/video-bios.c
new file mode 100644
index 000000000000..afea46c500cc
--- /dev/null
+++ b/arch/i386/boot/video-bios.c
@@ -0,0 +1,125 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/video-bios.c
13 *
14 * Standard video BIOS modes
15 *
16 * We have two options for this; silent and scanned.
17 */
18
19#include "boot.h"
20#include "video.h"
21
22__videocard video_bios;
23
24/* Set a conventional BIOS mode */
25static int set_bios_mode(u8 mode);
26
27static int bios_set_mode(struct mode_info *mi)
28{
29 return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
30}
31
32static int set_bios_mode(u8 mode)
33{
34 u16 ax;
35 u8 new_mode;
36
37 ax = mode; /* AH=0x00 Set Video Mode */
38 asm volatile(INT10
39 : "+a" (ax)
40 : : "ebx", "ecx", "edx", "esi", "edi");
41
42 ax = 0x0f00; /* Get Current Video Mode */
43 asm volatile(INT10
44 : "+a" (ax)
45 : : "ebx", "ecx", "edx", "esi", "edi");
46
47 do_restore = 1; /* Assume video contents was lost */
48 new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */
49
50 if (new_mode == mode)
51 return 0; /* Mode change OK */
52
53 if (new_mode != boot_params.screen_info.orig_video_mode) {
54 /* Mode setting failed, but we didn't end up where we
55 started. That's bad. Try to revert to the original
56 video mode. */
57 ax = boot_params.screen_info.orig_video_mode;
58 asm volatile(INT10
59 : "+a" (ax)
60 : : "ebx", "ecx", "edx", "esi", "edi");
61 }
62 return -1;
63}
64
65static int bios_probe(void)
66{
67 u8 mode;
68 u8 saved_mode = boot_params.screen_info.orig_video_mode;
69 u16 crtc;
70 struct mode_info *mi;
71 int nmodes = 0;
72
73 if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
74 return 0;
75
76 set_fs(0);
77 crtc = vga_crtc();
78
79 video_bios.modes = GET_HEAP(struct mode_info, 0);
80
81 for (mode = 0x14; mode <= 0x7f; mode++) {
82 if (heap_free() < sizeof(struct mode_info))
83 break;
84
85 if (mode_defined(VIDEO_FIRST_BIOS+mode))
86 continue;
87
88 if (set_bios_mode(mode))
89 continue;
90
91 /* Try to verify that it's a text mode. */
92
93 /* Attribute Controller: make graphics controller disabled */
94 if (in_idx(0x3c0, 0x10) & 0x01)
95 continue;
96
97 /* Graphics Controller: verify Alpha addressing enabled */
98 if (in_idx(0x3ce, 0x06) & 0x01)
99 continue;
100
101 /* CRTC cursor location low should be zero(?) */
102 if (in_idx(crtc, 0x0f))
103 continue;
104
105 mi = GET_HEAP(struct mode_info, 1);
106 mi->mode = VIDEO_FIRST_BIOS+mode;
107 mi->x = rdfs16(0x44a);
108 mi->y = rdfs8(0x484)+1;
109 nmodes++;
110 }
111
112 set_bios_mode(saved_mode);
113
114 return nmodes;
115}
116
117__videocard video_bios =
118{
119 .card_name = "BIOS (scanned)",
120 .probe = bios_probe,
121 .set_mode = bios_set_mode,
122 .unsafe = 1,
123 .xmode_first = VIDEO_FIRST_BIOS,
124 .xmode_n = 0x80,
125};
diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c
new file mode 100644
index 000000000000..e6aa9eb8d93a
--- /dev/null
+++ b/arch/i386/boot/video-vesa.c
@@ -0,0 +1,284 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/video-vesa.c
13 *
14 * VESA text modes
15 */
16
17#include "boot.h"
18#include "video.h"
19#include "vesa.h"
20
21/* VESA information */
22static struct vesa_general_info vginfo;
23static struct vesa_mode_info vminfo;
24
25__videocard video_vesa;
26
27static void vesa_store_mode_params_graphics(void);
28
29static int vesa_probe(void)
30{
31#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
32 u16 ax;
33 u16 mode;
34 addr_t mode_ptr;
35 struct mode_info *mi;
36 int nmodes = 0;
37
38 video_vesa.modes = GET_HEAP(struct mode_info, 0);
39
40 vginfo.signature = VBE2_MAGIC;
41
42 /* Optimistically assume a VESA BIOS is register-clean... */
43 ax = 0x4f00;
44 asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
45
46 if (ax != 0x004f ||
47 vginfo.signature != VESA_MAGIC ||
48 vginfo.version < 0x0102)
49 return 0; /* Not present */
50#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
51#ifdef CONFIG_VIDEO_VESA
52 set_fs(vginfo.video_mode_ptr.seg);
53 mode_ptr = vginfo.video_mode_ptr.off;
54
55 while ((mode = rdfs16(mode_ptr)) != 0xffff) {
56 mode_ptr += 2;
57
58 if (heap_free() < sizeof(struct mode_info))
59 break; /* Heap full, can't save mode info */
60
61 if (mode & ~0x1ff)
62 continue;
63
64 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
65
66 ax = 0x4f01;
67 asm("int $0x10"
68 : "+a" (ax), "=m" (vminfo)
69 : "c" (mode), "D" (&vminfo));
70
71 if (ax != 0x004f)
72 continue;
73
74 if ((vminfo.mode_attr & 0x15) == 0x05) {
75 /* Text Mode, TTY BIOS supported,
76 supported by hardware */
77 mi = GET_HEAP(struct mode_info, 1);
78 mi->mode = mode + VIDEO_FIRST_VESA;
79 mi->x = vminfo.h_res;
80 mi->y = vminfo.v_res;
81 nmodes++;
82 } else if ((vminfo.mode_attr & 0x99) == 0x99) {
83#ifdef CONFIG_FB
84 /* Graphics mode, color, linear frame buffer
85 supported -- register the mode but hide from
86 the menu. Only do this if framebuffer is
87 configured, however, otherwise the user will
88 be left without a screen. */
89 mi = GET_HEAP(struct mode_info, 1);
90 mi->mode = mode + VIDEO_FIRST_VESA;
91 mi->x = mi->y = 0;
92 nmodes++;
93#endif
94 }
95 }
96
97 return nmodes;
98#else
99 return 0;
100#endif /* CONFIG_VIDEO_VESA */
101}
102
103static int vesa_set_mode(struct mode_info *mode)
104{
105 u16 ax;
106 int is_graphic;
107 u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
108
109 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
110
111 ax = 0x4f01;
112 asm("int $0x10"
113 : "+a" (ax), "=m" (vminfo)
114 : "c" (vesa_mode), "D" (&vminfo));
115
116 if (ax != 0x004f)
117 return -1;
118
119 if ((vminfo.mode_attr & 0x15) == 0x05) {
120 /* It's a supported text mode */
121 is_graphic = 0;
122 } else if ((vminfo.mode_attr & 0x99) == 0x99) {
123 /* It's a graphics mode with linear frame buffer */
124 is_graphic = 1;
125 vesa_mode |= 0x4000; /* Request linear frame buffer */
126 } else {
127 return -1; /* Invalid mode */
128 }
129
130
131 ax = 0x4f02;
132 asm volatile("int $0x10"
133 : "+a" (ax)
134 : "b" (vesa_mode), "D" (0));
135
136 if (ax != 0x004f)
137 return -1;
138
139 graphic_mode = is_graphic;
140 if (!is_graphic) {
141 /* Text mode */
142 force_x = mode->x;
143 force_y = mode->y;
144 do_restore = 1;
145 } else {
146 /* Graphics mode */
147 vesa_store_mode_params_graphics();
148 }
149
150 return 0;
151}
152
153
154/* Switch DAC to 8-bit mode */
155static void vesa_dac_set_8bits(void)
156{
157 u8 dac_size = 6;
158
159 /* If possible, switch the DAC to 8-bit mode */
160 if (vginfo.capabilities & 1) {
161 u16 ax, bx;
162
163 ax = 0x4f08;
164 bx = 0x0800;
165 asm volatile(INT10
166 : "+a" (ax), "+b" (bx)
167 : : "ecx", "edx", "esi", "edi");
168
169 if (ax == 0x004f)
170 dac_size = bx >> 8;
171 }
172
173 /* Set the color sizes to the DAC size, and offsets to 0 */
174 boot_params.screen_info.red_size = dac_size;
175 boot_params.screen_info.green_size = dac_size;
176 boot_params.screen_info.blue_size = dac_size;
177 boot_params.screen_info.rsvd_size = dac_size;
178
179 boot_params.screen_info.red_pos = 0;
180 boot_params.screen_info.green_pos = 0;
181 boot_params.screen_info.blue_pos = 0;
182 boot_params.screen_info.rsvd_pos = 0;
183}
184
185/* Save the VESA protected mode info */
186static void vesa_store_pm_info(void)
187{
188 u16 ax, bx, di, es;
189
190 ax = 0x4f0a;
191 bx = di = 0;
192 asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
193 : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
194 : : "ecx", "esi");
195
196 if (ax != 0x004f)
197 return;
198
199 boot_params.screen_info.vesapm_seg = es;
200 boot_params.screen_info.vesapm_off = di;
201}
202
203/*
204 * Save video mode parameters for graphics mode
205 */
206static void vesa_store_mode_params_graphics(void)
207{
208 /* Tell the kernel we're in VESA graphics mode */
209 boot_params.screen_info.orig_video_isVGA = 0x23;
210
211 /* Mode parameters */
212 boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
213 boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
214 boot_params.screen_info.lfb_width = vminfo.h_res;
215 boot_params.screen_info.lfb_height = vminfo.v_res;
216 boot_params.screen_info.lfb_depth = vminfo.bpp;
217 boot_params.screen_info.pages = vminfo.image_planes;
218 boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
219 memcpy(&boot_params.screen_info.red_size,
220 &vminfo.rmask, 8);
221
222 /* General parameters */
223 boot_params.screen_info.lfb_size = vginfo.total_memory;
224
225 if (vminfo.bpp <= 8)
226 vesa_dac_set_8bits();
227
228 vesa_store_pm_info();
229}
230
231/*
232 * Save EDID information for the kernel; this is invoked, separately,
233 * after mode-setting.
234 */
235void vesa_store_edid(void)
236{
237#ifdef CONFIG_FIRMWARE_EDID
238 u16 ax, bx, cx, dx, di;
239
240 /* Apparently used as a nonsense token... */
241 memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
242
243 if (vginfo.version < 0x0200)
244 return; /* EDID requires VBE 2.0+ */
245
246 ax = 0x4f15; /* VBE DDC */
247 bx = 0x0000; /* Report DDC capabilities */
248 cx = 0; /* Controller 0 */
249 di = 0; /* ES:DI must be 0 by spec */
250
251 /* Note: The VBE DDC spec is different from the main VESA spec;
252 we genuinely have to assume all registers are destroyed here. */
253
254 asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
255 : "+a" (ax), "+b" (bx)
256 : "c" (cx), "D" (di)
257 : "esi");
258
259 if (ax != 0x004f)
260 return; /* No EDID */
261
262 /* BH = time in seconds to transfer EDD information */
263 /* BL = DDC level supported */
264
265 ax = 0x4f15; /* VBE DDC */
266 bx = 0x0001; /* Read EDID */
267 cx = 0; /* Controller 0 */
268 dx = 0; /* EDID block number */
269 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
270 asm(INT10
271 : "+a" (ax), "+b" (bx), "+d" (dx)
272 : "c" (cx), "D" (di)
273 : "esi");
274#endif /* CONFIG_FIRMWARE_EDID */
275}
276
277__videocard video_vesa =
278{
279 .card_name = "VESA",
280 .probe = vesa_probe,
281 .set_mode = vesa_set_mode,
282 .xmode_first = VIDEO_FIRST_VESA,
283 .xmode_n = 0x200,
284};
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c
new file mode 100644
index 000000000000..700d09a9c9b3
--- /dev/null
+++ b/arch/i386/boot/video-vga.c
@@ -0,0 +1,260 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/video-vga.c
13 *
14 * Common all-VGA modes
15 */
16
17#include "boot.h"
18#include "video.h"
19
20static struct mode_info vga_modes[] = {
21 { VIDEO_80x25, 80, 25 },
22 { VIDEO_8POINT, 80, 50 },
23 { VIDEO_80x43, 80, 43 },
24 { VIDEO_80x28, 80, 28 },
25 { VIDEO_80x30, 80, 30 },
26 { VIDEO_80x34, 80, 34 },
27 { VIDEO_80x60, 80, 60 },
28};
29
30static struct mode_info ega_modes[] = {
31 { VIDEO_80x25, 80, 25 },
32 { VIDEO_8POINT, 80, 43 },
33};
34
35static struct mode_info cga_modes[] = {
36 { VIDEO_80x25, 80, 25 },
37};
38
39__videocard video_vga;
40
41/* Set basic 80x25 mode */
42static u8 vga_set_basic_mode(void)
43{
44 u16 ax;
45 u8 rows;
46 u8 mode;
47
48#ifdef CONFIG_VIDEO_400_HACK
49 if (adapter >= ADAPTER_VGA) {
50 asm(INT10
51 : : "a" (0x1202), "b" (0x0030)
52 : "ecx", "edx", "esi", "edi");
53 }
54#endif
55
56 ax = 0x0f00;
57 asm(INT10
58 : "+a" (ax)
59 : : "ebx", "ecx", "edx", "esi", "edi");
60
61 mode = (u8)ax;
62
63 set_fs(0);
64 rows = rdfs8(0x484); /* rows minus one */
65
66#ifndef CONFIG_VIDEO_400_HACK
67 if ((ax == 0x5003 || ax == 0x5007) &&
68 (rows == 0 || rows == 24))
69 return mode;
70#endif
71
72 if (mode != 3 && mode != 7)
73 mode = 3;
74
75 /* Set the mode */
76 asm volatile(INT10
77 : : "a" (mode)
78 : "ebx", "ecx", "edx", "esi", "edi");
79 do_restore = 1;
80 return mode;
81}
82
83static void vga_set_8font(void)
84{
85 /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
86
87 /* Set 8x8 font */
88 asm volatile(INT10 : : "a" (0x1112), "b" (0));
89
90 /* Use alternate print screen */
91 asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
92
93 /* Turn off cursor emulation */
94 asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
95
96 /* Cursor is scan lines 6-7 */
97 asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
98}
99
100static void vga_set_14font(void)
101{
102 /* Set 9x14 font - 80x28 on VGA */
103
104 /* Set 9x14 font */
105 asm volatile(INT10 : : "a" (0x1111), "b" (0));
106
107 /* Turn off cursor emulation */
108 asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
109
110 /* Cursor is scan lines 11-12 */
111 asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
112}
113
114static void vga_set_80x43(void)
115{
116 /* Set 80x43 mode on VGA (not EGA) */
117
118 /* Set 350 scans */
119 asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
120
121 /* Reset video mode */
122 asm volatile(INT10 : : "a" (0x0003));
123
124 vga_set_8font();
125}
126
127/* I/O address of the VGA CRTC */
128u16 vga_crtc(void)
129{
130 return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
131}
132
133static void vga_set_480_scanlines(int end)
134{
135 u16 crtc;
136 u8 csel;
137
138 crtc = vga_crtc();
139
140 out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
141 out_idx(0x0b, crtc, 0x06); /* Vertical total */
142 out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
143 out_idx(0xea, crtc, 0x10); /* Vertical sync start */
144 out_idx(end, crtc, 0x12); /* Vertical display end */
145 out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
146 out_idx(0x04, crtc, 0x16); /* Vertical blank end */
147 csel = inb(0x3cc);
148 csel &= 0x0d;
149 csel |= 0xe2;
150 outb(csel, 0x3cc);
151}
152
153static void vga_set_80x30(void)
154{
155 vga_set_480_scanlines(0xdf);
156}
157
158static void vga_set_80x34(void)
159{
160 vga_set_14font();
161 vga_set_480_scanlines(0xdb);
162}
163
164static void vga_set_80x60(void)
165{
166 vga_set_8font();
167 vga_set_480_scanlines(0xdf);
168}
169
170static int vga_set_mode(struct mode_info *mode)
171{
172 /* Set the basic mode */
173 vga_set_basic_mode();
174
175 /* Override a possibly broken BIOS */
176 force_x = mode->x;
177 force_y = mode->y;
178
179 switch (mode->mode) {
180 case VIDEO_80x25:
181 break;
182 case VIDEO_8POINT:
183 vga_set_8font();
184 break;
185 case VIDEO_80x43:
186 vga_set_80x43();
187 break;
188 case VIDEO_80x28:
189 vga_set_14font();
190 break;
191 case VIDEO_80x30:
192 vga_set_80x30();
193 break;
194 case VIDEO_80x34:
195 vga_set_80x34();
196 break;
197 case VIDEO_80x60:
198 vga_set_80x60();
199 break;
200 }
201
202 return 0;
203}
204
205/*
206 * Note: this probe includes basic information required by all
207 * systems. It should be executed first, by making sure
208 * video-vga.c is listed first in the Makefile.
209 */
210static int vga_probe(void)
211{
212 static const char *card_name[] = {
213 "CGA/MDA/HGC", "EGA", "VGA"
214 };
215 static struct mode_info *mode_lists[] = {
216 cga_modes,
217 ega_modes,
218 vga_modes,
219 };
220 static int mode_count[] = {
221 sizeof(cga_modes)/sizeof(struct mode_info),
222 sizeof(ega_modes)/sizeof(struct mode_info),
223 sizeof(vga_modes)/sizeof(struct mode_info),
224 };
225 u8 vga_flag;
226
227 asm(INT10
228 : "=b" (boot_params.screen_info.orig_video_ega_bx)
229 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
230 : "ecx", "edx", "esi", "edi");
231
232 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
233 if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
234 /* EGA/VGA */
235 asm(INT10
236 : "=a" (vga_flag)
237 : "a" (0x1a00)
238 : "ebx", "ecx", "edx", "esi", "edi");
239
240 if (vga_flag == 0x1a) {
241 adapter = ADAPTER_VGA;
242 boot_params.screen_info.orig_video_isVGA = 1;
243 } else {
244 adapter = ADAPTER_EGA;
245 }
246 } else {
247 adapter = ADAPTER_CGA;
248 }
249
250 video_vga.modes = mode_lists[adapter];
251 video_vga.card_name = card_name[adapter];
252 return mode_count[adapter];
253}
254
255__videocard video_vga =
256{
257 .card_name = "VGA",
258 .probe = vga_probe,
259 .set_mode = vga_set_mode,
260};
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
deleted file mode 100644
index 8143c9516cb4..000000000000
--- a/arch/i386/boot/video.S
+++ /dev/null
@@ -1,2043 +0,0 @@
1/* video.S
2 *
3 * Display adapter & video mode setup, version 2.13 (14-May-99)
4 *
5 * Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
6 * Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
7 *
8 * Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
9 *
10 * For further information, look at Documentation/svga.txt.
11 *
12 */
13
14/* Enable autodetection of SVGA adapters and modes. */
15#undef CONFIG_VIDEO_SVGA
16
17/* Enable autodetection of VESA modes */
18#define CONFIG_VIDEO_VESA
19
20/* Enable compacting of mode table */
21#define CONFIG_VIDEO_COMPACT
22
23/* Retain screen contents when switching modes */
24#define CONFIG_VIDEO_RETAIN
25
26/* Enable local mode list */
27#undef CONFIG_VIDEO_LOCAL
28
29/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
30#undef CONFIG_VIDEO_400_HACK
31
32/* Hack that lets you force specific BIOS mode ID and specific dimensions */
33#undef CONFIG_VIDEO_GFX_HACK
34#define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */
35#define VIDEO_GFX_BIOS_BX 0x0102
36#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */
37
38/* This code uses an extended set of video mode numbers. These include:
39 * Aliases for standard modes
40 * NORMAL_VGA (-1)
41 * EXTENDED_VGA (-2)
42 * ASK_VGA (-3)
43 * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
44 * of compatibility when extending the table. These are between 0x00 and 0xff.
45 */
46#define VIDEO_FIRST_MENU 0x0000
47
48/* Standard BIOS video modes (BIOS number + 0x0100) */
49#define VIDEO_FIRST_BIOS 0x0100
50
51/* VESA BIOS video modes (VESA number + 0x0200) */
52#define VIDEO_FIRST_VESA 0x0200
53
54/* Video7 special modes (BIOS number + 0x0900) */
55#define VIDEO_FIRST_V7 0x0900
56
57/* Special video modes */
58#define VIDEO_FIRST_SPECIAL 0x0f00
59#define VIDEO_80x25 0x0f00
60#define VIDEO_8POINT 0x0f01
61#define VIDEO_80x43 0x0f02
62#define VIDEO_80x28 0x0f03
63#define VIDEO_CURRENT_MODE 0x0f04
64#define VIDEO_80x30 0x0f05
65#define VIDEO_80x34 0x0f06
66#define VIDEO_80x60 0x0f07
67#define VIDEO_GFX_HACK 0x0f08
68#define VIDEO_LAST_SPECIAL 0x0f09
69
70/* Video modes given by resolution */
71#define VIDEO_FIRST_RESOLUTION 0x1000
72
73/* The "recalculate timings" flag */
74#define VIDEO_RECALC 0x8000
75
76/* Positions of various video parameters passed to the kernel */
77/* (see also include/linux/tty.h) */
78#define PARAM_CURSOR_POS 0x00
79#define PARAM_VIDEO_PAGE 0x04
80#define PARAM_VIDEO_MODE 0x06
81#define PARAM_VIDEO_COLS 0x07
82#define PARAM_VIDEO_EGA_BX 0x0a
83#define PARAM_VIDEO_LINES 0x0e
84#define PARAM_HAVE_VGA 0x0f
85#define PARAM_FONT_POINTS 0x10
86
87#define PARAM_LFB_WIDTH 0x12
88#define PARAM_LFB_HEIGHT 0x14
89#define PARAM_LFB_DEPTH 0x16
90#define PARAM_LFB_BASE 0x18
91#define PARAM_LFB_SIZE 0x1c
92#define PARAM_LFB_LINELENGTH 0x24
93#define PARAM_LFB_COLORS 0x26
94#define PARAM_VESAPM_SEG 0x2e
95#define PARAM_VESAPM_OFF 0x30
96#define PARAM_LFB_PAGES 0x32
97#define PARAM_VESA_ATTRIB 0x34
98#define PARAM_CAPABILITIES 0x36
99
100/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
101#ifdef CONFIG_VIDEO_RETAIN
102#define DO_STORE call store_screen
103#else
104#define DO_STORE
105#endif /* CONFIG_VIDEO_RETAIN */
106
107# This is the main entry point called by setup.S
108# %ds *must* be pointing to the bootsector
109video: pushw %ds # We use different segments
110 pushw %ds # FS contains original DS
111 popw %fs
112 pushw %cs # DS is equal to CS
113 popw %ds
114 pushw %cs # ES is equal to CS
115 popw %es
116 xorw %ax, %ax
117 movw %ax, %gs # GS is zero
118 cld
119 call basic_detect # Basic adapter type testing (EGA/VGA/MDA/CGA)
120#ifdef CONFIG_VIDEO_SELECT
121 movw %fs:(0x01fa), %ax # User selected video mode
122 cmpw $ASK_VGA, %ax # Bring up the menu
123 jz vid2
124
125 call mode_set # Set the mode
126 jc vid1
127
128 leaw badmdt, %si # Invalid mode ID
129 call prtstr
130vid2: call mode_menu
131vid1:
132#ifdef CONFIG_VIDEO_RETAIN
133 call restore_screen # Restore screen contents
134#endif /* CONFIG_VIDEO_RETAIN */
135 call store_edid
136#endif /* CONFIG_VIDEO_SELECT */
137 call mode_params # Store mode parameters
138 popw %ds # Restore original DS
139 ret
140
141# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
142basic_detect:
143 movb $0, %fs:(PARAM_HAVE_VGA)
144 movb $0x12, %ah # Check EGA/VGA
145 movb $0x10, %bl
146 int $0x10
147 movw %bx, %fs:(PARAM_VIDEO_EGA_BX) # Identifies EGA to the kernel
148 cmpb $0x10, %bl # No, it's a CGA/MDA/HGA card.
149 je basret
150
151 incb adapter
152 movw $0x1a00, %ax # Check EGA or VGA?
153 int $0x10
154 cmpb $0x1a, %al # 1a means VGA...
155 jne basret # anything else is EGA.
156
157 incb %fs:(PARAM_HAVE_VGA) # We've detected a VGA
158 incb adapter
159basret: ret
160
161# Store the video mode parameters for later usage by the kernel.
162# This is done by asking the BIOS except for the rows/columns
163# parameters in the default 80x25 mode -- these are set directly,
164# because some very obscure BIOSes supply insane values.
165mode_params:
166#ifdef CONFIG_VIDEO_SELECT
167 cmpb $0, graphic_mode
168 jnz mopar_gr
169#endif
170 movb $0x03, %ah # Read cursor position
171 xorb %bh, %bh
172 int $0x10
173 movw %dx, %fs:(PARAM_CURSOR_POS)
174 movb $0x0f, %ah # Read page/mode/width
175 int $0x10
176 movw %bx, %fs:(PARAM_VIDEO_PAGE)
177 movw %ax, %fs:(PARAM_VIDEO_MODE) # Video mode and screen width
178 cmpb $0x7, %al # MDA/HGA => segment differs
179 jnz mopar0
180
181 movw $0xb000, video_segment
182mopar0: movw %gs:(0x485), %ax # Font size
183 movw %ax, %fs:(PARAM_FONT_POINTS) # (valid only on EGA/VGA)
184 movw force_size, %ax # Forced size?
185 orw %ax, %ax
186 jz mopar1
187
188 movb %ah, %fs:(PARAM_VIDEO_COLS)
189 movb %al, %fs:(PARAM_VIDEO_LINES)
190 ret
191
192mopar1: movb $25, %al
193 cmpb $0, adapter # If we are on CGA/MDA/HGA, the
194 jz mopar2 # screen must have 25 lines.
195
196 movb %gs:(0x484), %al # On EGA/VGA, use the EGA+ BIOS
197 incb %al # location of max lines.
198mopar2: movb %al, %fs:(PARAM_VIDEO_LINES)
199 ret
200
201#ifdef CONFIG_VIDEO_SELECT
202# Fetching of VESA frame buffer parameters
203mopar_gr:
204 leaw modelist+1024, %di
205 movb $0x23, %fs:(PARAM_HAVE_VGA)
206 movw 16(%di), %ax
207 movw %ax, %fs:(PARAM_LFB_LINELENGTH)
208 movw 18(%di), %ax
209 movw %ax, %fs:(PARAM_LFB_WIDTH)
210 movw 20(%di), %ax
211 movw %ax, %fs:(PARAM_LFB_HEIGHT)
212 movb 25(%di), %al
213 movb $0, %ah
214 movw %ax, %fs:(PARAM_LFB_DEPTH)
215 movb 29(%di), %al
216 movb $0, %ah
217 movw %ax, %fs:(PARAM_LFB_PAGES)
218 movl 40(%di), %eax
219 movl %eax, %fs:(PARAM_LFB_BASE)
220 movl 31(%di), %eax
221 movl %eax, %fs:(PARAM_LFB_COLORS)
222 movl 35(%di), %eax
223 movl %eax, %fs:(PARAM_LFB_COLORS+4)
224 movw 0(%di), %ax
225 movw %ax, %fs:(PARAM_VESA_ATTRIB)
226
227# get video mem size
228 leaw modelist+1024, %di
229 movw $0x4f00, %ax
230 int $0x10
231 xorl %eax, %eax
232 movw 18(%di), %ax
233 movl %eax, %fs:(PARAM_LFB_SIZE)
234
235# store mode capabilities
236 movl 10(%di), %eax
237 movl %eax, %fs:(PARAM_CAPABILITIES)
238
239# switching the DAC to 8-bit is for <= 8 bpp only
240 movw %fs:(PARAM_LFB_DEPTH), %ax
241 cmpw $8, %ax
242 jg dac_done
243
244# get DAC switching capability
245 xorl %eax, %eax
246 movb 10(%di), %al
247 testb $1, %al
248 jz dac_set
249
250# attempt to switch DAC to 8-bit
251 movw $0x4f08, %ax
252 movw $0x0800, %bx
253 int $0x10
254 cmpw $0x004f, %ax
255 jne dac_set
256 movb %bh, dac_size # store actual DAC size
257
258dac_set:
259# set color size to DAC size
260 movb dac_size, %al
261 movb %al, %fs:(PARAM_LFB_COLORS+0)
262 movb %al, %fs:(PARAM_LFB_COLORS+2)
263 movb %al, %fs:(PARAM_LFB_COLORS+4)
264 movb %al, %fs:(PARAM_LFB_COLORS+6)
265
266# set color offsets to 0
267 movb $0, %fs:(PARAM_LFB_COLORS+1)
268 movb $0, %fs:(PARAM_LFB_COLORS+3)
269 movb $0, %fs:(PARAM_LFB_COLORS+5)
270 movb $0, %fs:(PARAM_LFB_COLORS+7)
271
272dac_done:
273# get protected mode interface informations
274 movw $0x4f0a, %ax
275 xorw %bx, %bx
276 xorw %di, %di
277 int $0x10
278 cmp $0x004f, %ax
279 jnz no_pm
280
281 movw %es, %fs:(PARAM_VESAPM_SEG)
282 movw %di, %fs:(PARAM_VESAPM_OFF)
283no_pm: ret
284
285# The video mode menu
286mode_menu:
287 leaw keymsg, %si # "Return/Space/Timeout" message
288 call prtstr
289 call flush
290nokey: call getkt
291
292 cmpb $0x0d, %al # ENTER ?
293 je listm # yes - manual mode selection
294
295 cmpb $0x20, %al # SPACE ?
296 je defmd1 # no - repeat
297
298 call beep
299 jmp nokey
300
301defmd1: ret # No mode chosen? Default 80x25
302
303listm: call mode_table # List mode table
304listm0: leaw name_bann, %si # Print adapter name
305 call prtstr
306 movw card_name, %si
307 orw %si, %si
308 jnz an2
309
310 movb adapter, %al
311 leaw old_name, %si
312 orb %al, %al
313 jz an1
314
315 leaw ega_name, %si
316 decb %al
317 jz an1
318
319 leaw vga_name, %si
320 jmp an1
321
322an2: call prtstr
323 leaw svga_name, %si
324an1: call prtstr
325 leaw listhdr, %si # Table header
326 call prtstr
327 movb $0x30, %dl # DL holds mode number
328 leaw modelist, %si
329lm1: cmpw $ASK_VGA, (%si) # End?
330 jz lm2
331
332 movb %dl, %al # Menu selection number
333 call prtchr
334 call prtsp2
335 lodsw
336 call prthw # Mode ID
337 call prtsp2
338 movb 0x1(%si), %al
339 call prtdec # Rows
340 movb $0x78, %al # the letter 'x'
341 call prtchr
342 lodsw
343 call prtdec # Columns
344 movb $0x0d, %al # New line
345 call prtchr
346 movb $0x0a, %al
347 call prtchr
348 incb %dl # Next character
349 cmpb $0x3a, %dl
350 jnz lm1
351
352 movb $0x61, %dl
353 jmp lm1
354
355lm2: leaw prompt, %si # Mode prompt
356 call prtstr
357 leaw edit_buf, %di # Editor buffer
358lm3: call getkey
359 cmpb $0x0d, %al # Enter?
360 jz lment
361
362 cmpb $0x08, %al # Backspace?
363 jz lmbs
364
365 cmpb $0x20, %al # Printable?
366 jc lm3
367
368 cmpw $edit_buf+4, %di # Enough space?
369 jz lm3
370
371 stosb
372 call prtchr
373 jmp lm3
374
375lmbs: cmpw $edit_buf, %di # Backspace
376 jz lm3
377
378 decw %di
379 movb $0x08, %al
380 call prtchr
381 call prtspc
382 movb $0x08, %al
383 call prtchr
384 jmp lm3
385
386lment: movb $0, (%di)
387 leaw crlft, %si
388 call prtstr
389 leaw edit_buf, %si
390 cmpb $0, (%si) # Empty string = default mode
391 jz lmdef
392
393 cmpb $0, 1(%si) # One character = menu selection
394 jz mnusel
395
396 cmpw $0x6373, (%si) # "scan" => mode scanning
397 jnz lmhx
398
399 cmpw $0x6e61, 2(%si)
400 jz lmscan
401
402lmhx: xorw %bx, %bx # Else => mode ID in hex
403lmhex: lodsb
404 orb %al, %al
405 jz lmuse1
406
407 subb $0x30, %al
408 jc lmbad
409
410 cmpb $10, %al
411 jc lmhx1
412
413 subb $7, %al
414 andb $0xdf, %al
415 cmpb $10, %al
416 jc lmbad
417
418 cmpb $16, %al
419 jnc lmbad
420
421lmhx1: shlw $4, %bx
422 orb %al, %bl
423 jmp lmhex
424
425lmuse1: movw %bx, %ax
426 jmp lmuse
427
428mnusel: lodsb # Menu selection
429 xorb %ah, %ah
430 subb $0x30, %al
431 jc lmbad
432
433 cmpb $10, %al
434 jc lmuse
435
436 cmpb $0x61-0x30, %al
437 jc lmbad
438
439 subb $0x61-0x30-10, %al
440 cmpb $36, %al
441 jnc lmbad
442
443lmuse: call mode_set
444 jc lmdef
445
446lmbad: leaw unknt, %si
447 call prtstr
448 jmp lm2
449lmscan: cmpb $0, adapter # Scanning only on EGA/VGA
450 jz lmbad
451
452 movw $0, mt_end # Scanning of modes is
453 movb $1, scanning # done as new autodetection.
454 call mode_table
455 jmp listm0
456lmdef: ret
457
458# Additional parts of mode_set... (relative jumps, you know)
459setv7: # Video7 extended modes
460 DO_STORE
461 subb $VIDEO_FIRST_V7>>8, %bh
462 movw $0x6f05, %ax
463 int $0x10
464 stc
465 ret
466
467_setrec: jmp setrec # Ugly...
468_set_80x25: jmp set_80x25
469
470# Aliases for backward compatibility.
471setalias:
472 movw $VIDEO_80x25, %ax
473 incw %bx
474 jz mode_set
475
476 movb $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
477 incw %bx
478 jnz setbad # Fall-through!
479
480# Setting of user mode (AX=mode ID) => CF=success
481mode_set:
482 movw %ax, %fs:(0x01fa) # Store mode for use in acpi_wakeup.S
483 movw %ax, %bx
484 cmpb $0xff, %ah
485 jz setalias
486
487 testb $VIDEO_RECALC>>8, %ah
488 jnz _setrec
489
490 cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah
491 jnc setres
492
493 cmpb $VIDEO_FIRST_SPECIAL>>8, %ah
494 jz setspc
495
496 cmpb $VIDEO_FIRST_V7>>8, %ah
497 jz setv7
498
499 cmpb $VIDEO_FIRST_VESA>>8, %ah
500 jnc check_vesa
501
502 orb %ah, %ah
503 jz setmenu
504
505 decb %ah
506 jz setbios
507
508setbad: clc
509 movb $0, do_restore # The screen needn't be restored
510 ret
511
512setvesa:
513 DO_STORE
514 subb $VIDEO_FIRST_VESA>>8, %bh
515 movw $0x4f02, %ax # VESA BIOS mode set call
516 int $0x10
517 cmpw $0x004f, %ax # AL=4f if implemented
518 jnz setbad # AH=0 if OK
519
520 stc
521 ret
522
523setbios:
524 DO_STORE
525 int $0x10 # Standard BIOS mode set call
526 pushw %bx
527 movb $0x0f, %ah # Check if really set
528 int $0x10
529 popw %bx
530 cmpb %bl, %al
531 jnz setbad
532
533 stc
534 ret
535
536setspc: xorb %bh, %bh # Set special mode
537 cmpb $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
538 jnc setbad
539
540 addw %bx, %bx
541 jmp *spec_inits(%bx)
542
543setmenu:
544 orb %al, %al # 80x25 is an exception
545 jz _set_80x25
546
547 pushw %bx # Set mode chosen from menu
548 call mode_table # Build the mode table
549 popw %ax
550 shlw $2, %ax
551 addw %ax, %si
552 cmpw %di, %si
553 jnc setbad
554
555 movw (%si), %ax # Fetch mode ID
556_m_s: jmp mode_set
557
558setres: pushw %bx # Set mode chosen by resolution
559 call mode_table
560 popw %bx
561 xchgb %bl, %bh
562setr1: lodsw
563 cmpw $ASK_VGA, %ax # End of the list?
564 jz setbad
565
566 lodsw
567 cmpw %bx, %ax
568 jnz setr1
569
570 movw -4(%si), %ax # Fetch mode ID
571 jmp _m_s
572
573check_vesa:
574#ifdef CONFIG_FIRMWARE_EDID
575 leaw modelist+1024, %di
576 movw $0x4f00, %ax
577 int $0x10
578 cmpw $0x004f, %ax
579 jnz setbad
580
581 movw 4(%di), %ax
582 movw %ax, vbe_version
583#endif
584 leaw modelist+1024, %di
585 subb $VIDEO_FIRST_VESA>>8, %bh
586 movw %bx, %cx # Get mode information structure
587 movw $0x4f01, %ax
588 int $0x10
589 addb $VIDEO_FIRST_VESA>>8, %bh
590 cmpw $0x004f, %ax
591 jnz setbad
592
593 movb (%di), %al # Check capabilities.
594 andb $0x19, %al
595 cmpb $0x09, %al
596 jz setvesa # This is a text mode
597
598 movb (%di), %al # Check capabilities.
599 andb $0x99, %al
600 cmpb $0x99, %al
601 jnz _setbad # Doh! No linear frame buffer.
602
603 subb $VIDEO_FIRST_VESA>>8, %bh
604 orw $0x4000, %bx # Use linear frame buffer
605 movw $0x4f02, %ax # VESA BIOS mode set call
606 int $0x10
607 cmpw $0x004f, %ax # AL=4f if implemented
608 jnz _setbad # AH=0 if OK
609
610 movb $1, graphic_mode # flag graphic mode
611 movb $0, do_restore # no screen restore
612 stc
613 ret
614
615_setbad: jmp setbad # Ugly...
616
617# Recalculate vertical display end registers -- this fixes various
618# inconsistencies of extended modes on many adapters. Called when
619# the VIDEO_RECALC flag is set in the mode ID.
620
621setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode
622 call mode_set
623 jnc rct3
624
625 movw %gs:(0x485), %ax # Font size in pixels
626 movb %gs:(0x484), %bl # Number of rows
627 incb %bl
628 mulb %bl # Number of visible
629 decw %ax # scan lines - 1
630 movw $0x3d4, %dx
631 movw %ax, %bx
632 movb $0x12, %al # Lower 8 bits
633 movb %bl, %ah
634 outw %ax, %dx
635 movb $0x07, %al # Bits 8 and 9 in the overflow register
636 call inidx
637 xchgb %al, %ah
638 andb $0xbd, %ah
639 shrb %bh
640 jnc rct1
641 orb $0x02, %ah
642rct1: shrb %bh
643 jnc rct2
644 orb $0x40, %ah
645rct2: movb $0x07, %al
646 outw %ax, %dx
647 stc
648rct3: ret
649
650# Table of routines for setting of the special modes.
651spec_inits:
652 .word set_80x25
653 .word set_8pixel
654 .word set_80x43
655 .word set_80x28
656 .word set_current
657 .word set_80x30
658 .word set_80x34
659 .word set_80x60
660 .word set_gfx
661
662# Set the 80x25 mode. If already set, do nothing.
663set_80x25:
664 movw $0x5019, force_size # Override possibly broken BIOS
665use_80x25:
666#ifdef CONFIG_VIDEO_400_HACK
667 movw $0x1202, %ax # Force 400 scan lines
668 movb $0x30, %bl
669 int $0x10
670#else
671 movb $0x0f, %ah # Get current mode ID
672 int $0x10
673 cmpw $0x5007, %ax # Mode 7 (80x25 mono) is the only one available
674 jz st80 # on CGA/MDA/HGA and is also available on EGAM
675
676 cmpw $0x5003, %ax # Unknown mode, force 80x25 color
677 jnz force3
678
679st80: cmpb $0, adapter # CGA/MDA/HGA => mode 3/7 is always 80x25
680 jz set80
681
682 movb %gs:(0x0484), %al # This is EGA+ -- beware of 80x50 etc.
683 orb %al, %al # Some buggy BIOS'es set 0 rows
684 jz set80
685
686 cmpb $24, %al # It's hopefully correct
687 jz set80
688#endif /* CONFIG_VIDEO_400_HACK */
689force3: DO_STORE
690 movw $0x0003, %ax # Forced set
691 int $0x10
692set80: stc
693 ret
694
695# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
696set_8pixel:
697 DO_STORE
698 call use_80x25 # The base is 80x25
699set_8pt:
700 movw $0x1112, %ax # Use 8x8 font
701 xorb %bl, %bl
702 int $0x10
703 movw $0x1200, %ax # Use alternate print screen
704 movb $0x20, %bl
705 int $0x10
706 movw $0x1201, %ax # Turn off cursor emulation
707 movb $0x34, %bl
708 int $0x10
709 movb $0x01, %ah # Define cursor scan lines 6-7
710 movw $0x0607, %cx
711 int $0x10
712set_current:
713 stc
714 ret
715
716# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
717# 80x25 mode with 14-point fonts instead of 16-point.
718set_80x28:
719 DO_STORE
720 call use_80x25 # The base is 80x25
721set14: movw $0x1111, %ax # Use 9x14 font
722 xorb %bl, %bl
723 int $0x10
724 movb $0x01, %ah # Define cursor scan lines 11-12
725 movw $0x0b0c, %cx
726 int $0x10
727 stc
728 ret
729
730# Set the 80x43 mode. This mode is works on all VGA's.
731# It's a 350-scanline mode with 8-pixel font.
732set_80x43:
733 DO_STORE
734 movw $0x1201, %ax # Set 350 scans
735 movb $0x30, %bl
736 int $0x10
737 movw $0x0003, %ax # Reset video mode
738 int $0x10
739 jmp set_8pt # Use 8-pixel font
740
741# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
742set_80x30:
743 call use_80x25 # Start with real 80x25
744 DO_STORE
745 movw $0x3cc, %dx # Get CRTC port
746 inb %dx, %al
747 movb $0xd4, %dl
748 rorb %al # Mono or color?
749 jc set48a
750
751 movb $0xb4, %dl
752set48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7)
753 call outidx
754 movw $0x0b06, %ax # Vertical total
755 call outidx
756 movw $0x3e07, %ax # (Vertical) overflow
757 call outidx
758 movw $0xea10, %ax # Vertical sync start
759 call outidx
760 movw $0xdf12, %ax # Vertical display end
761 call outidx
762 movw $0xe715, %ax # Vertical blank start
763 call outidx
764 movw $0x0416, %ax # Vertical blank end
765 call outidx
766 pushw %dx
767 movb $0xcc, %dl # Misc output register (read)
768 inb %dx, %al
769 movb $0xc2, %dl # (write)
770 andb $0x0d, %al # Preserve clock select bits and color bit
771 orb $0xe2, %al # Set correct sync polarity
772 outb %al, %dx
773 popw %dx
774 movw $0x501e, force_size
775 stc # That's all.
776 ret
777
778# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
779set_80x34:
780 call set_80x30 # Set 480 scans
781 call set14 # And 14-pt font
782 movw $0xdb12, %ax # VGA vertical display end
783 movw $0x5022, force_size
784setvde: call outidx
785 stc
786 ret
787
788# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
789set_80x60:
790 call set_80x30 # Set 480 scans
791 call set_8pt # And 8-pt font
792 movw $0xdf12, %ax # VGA vertical display end
793 movw $0x503c, force_size
794 jmp setvde
795
796# Special hack for ThinkPad graphics
797set_gfx:
798#ifdef CONFIG_VIDEO_GFX_HACK
799 movw $VIDEO_GFX_BIOS_AX, %ax
800 movw $VIDEO_GFX_BIOS_BX, %bx
801 int $0x10
802 movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size
803 stc
804#endif
805 ret
806
807#ifdef CONFIG_VIDEO_RETAIN
808
809# Store screen contents to temporary buffer.
810store_screen:
811 cmpb $0, do_restore # Already stored?
812 jnz stsr
813
814 testb $CAN_USE_HEAP, loadflags # Have we space for storing?
815 jz stsr
816
817 pushw %ax
818 pushw %bx
819 pushw force_size # Don't force specific size
820 movw $0, force_size
821 call mode_params # Obtain params of current mode
822 popw force_size
823 movb %fs:(PARAM_VIDEO_LINES), %ah
824 movb %fs:(PARAM_VIDEO_COLS), %al
825 movw %ax, %bx # BX=dimensions
826 mulb %ah
827 movw %ax, %cx # CX=number of characters
828 addw %ax, %ax # Calculate image size
829 addw $modelist+1024+4, %ax
830 cmpw heap_end_ptr, %ax
831 jnc sts1 # Unfortunately, out of memory
832
833 movw %fs:(PARAM_CURSOR_POS), %ax # Store mode params
834 leaw modelist+1024, %di
835 stosw
836 movw %bx, %ax
837 stosw
838 pushw %ds # Store the screen
839 movw video_segment, %ds
840 xorw %si, %si
841 rep
842 movsw
843 popw %ds
844 incb do_restore # Screen will be restored later
845sts1: popw %bx
846 popw %ax
847stsr: ret
848
849# Restore screen contents from temporary buffer.
850restore_screen:
851 cmpb $0, do_restore # Has the screen been stored?
852 jz res1
853
854 call mode_params # Get parameters of current mode
855 movb %fs:(PARAM_VIDEO_LINES), %cl
856 movb %fs:(PARAM_VIDEO_COLS), %ch
857 leaw modelist+1024, %si # Screen buffer
858 lodsw # Set cursor position
859 movw %ax, %dx
860 cmpb %cl, %dh
861 jc res2
862
863 movb %cl, %dh
864 decb %dh
865res2: cmpb %ch, %dl
866 jc res3
867
868 movb %ch, %dl
869 decb %dl
870res3: movb $0x02, %ah
871 movb $0x00, %bh
872 int $0x10
873 lodsw # Display size
874 movb %ah, %dl # DL=number of lines
875 movb $0, %ah # BX=phys. length of orig. line
876 movw %ax, %bx
877 cmpb %cl, %dl # Too many?
878 jc res4
879
880 pushw %ax
881 movb %dl, %al
882 subb %cl, %al
883 mulb %bl
884 addw %ax, %si
885 addw %ax, %si
886 popw %ax
887 movb %cl, %dl
888res4: cmpb %ch, %al # Too wide?
889 jc res5
890
891 movb %ch, %al # AX=width of src. line
892res5: movb $0, %cl
893 xchgb %ch, %cl
894 movw %cx, %bp # BP=width of dest. line
895 pushw %es
896 movw video_segment, %es
897 xorw %di, %di # Move the data
898 addw %bx, %bx # Convert BX and BP to _bytes_
899 addw %bp, %bp
900res6: pushw %si
901 pushw %di
902 movw %ax, %cx
903 rep
904 movsw
905 popw %di
906 popw %si
907 addw %bp, %di
908 addw %bx, %si
909 decb %dl
910 jnz res6
911
912 popw %es # Done
913res1: ret
914#endif /* CONFIG_VIDEO_RETAIN */
915
916# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
917outidx: outb %al, %dx
918 pushw %ax
919 movb %ah, %al
920 incw %dx
921 outb %al, %dx
922 decw %dx
923 popw %ax
924 ret
925
926# Build the table of video modes (stored after the setup.S code at the
927# `modelist' label. Each video mode record looks like:
928# .word MODE-ID (our special mode ID (see above))
929# .byte rows (number of rows)
930# .byte columns (number of columns)
931# Returns address of the end of the table in DI, the end is marked
932# with a ASK_VGA ID.
933mode_table:
934 movw mt_end, %di # Already filled?
935 orw %di, %di
936 jnz mtab1x
937
938 leaw modelist, %di # Store standard modes:
939 movl $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
940 stosl
941 movb adapter, %al # CGA/MDA/HGA -- no more modes
942 orb %al, %al
943 jz mtabe
944
945 decb %al
946 jnz mtabv
947
948 movl $VIDEO_8POINT + 0x502b0000, %eax # The 80x43 EGA mode
949 stosl
950 jmp mtabe
951
952mtab1x: jmp mtab1
953
954mtabv: leaw vga_modes, %si # All modes for std VGA
955 movw $vga_modes_end-vga_modes, %cx
956 rep # I'm unable to use movsw as I don't know how to store a half
957 movsb # of the expression above to cx without using explicit shr.
958
959 cmpb $0, scanning # Mode scan requested?
960 jz mscan1
961
962 call mode_scan
963mscan1:
964
965#ifdef CONFIG_VIDEO_LOCAL
966 call local_modes
967#endif /* CONFIG_VIDEO_LOCAL */
968
969#ifdef CONFIG_VIDEO_VESA
970 call vesa_modes # Detect VESA VGA modes
971#endif /* CONFIG_VIDEO_VESA */
972
973#ifdef CONFIG_VIDEO_SVGA
974 cmpb $0, scanning # Bypass when scanning
975 jnz mscan2
976
977 call svga_modes # Detect SVGA cards & modes
978mscan2:
979#endif /* CONFIG_VIDEO_SVGA */
980
981mtabe:
982
983#ifdef CONFIG_VIDEO_COMPACT
984 leaw modelist, %si
985 movw %di, %dx
986 movw %si, %di
987cmt1: cmpw %dx, %si # Scan all modes
988 jz cmt2
989
990 leaw modelist, %bx # Find in previous entries
991 movw 2(%si), %cx
992cmt3: cmpw %bx, %si
993 jz cmt4
994
995 cmpw 2(%bx), %cx # Found => don't copy this entry
996 jz cmt5
997
998 addw $4, %bx
999 jmp cmt3
1000
1001cmt4: movsl # Copy entry
1002 jmp cmt1
1003
1004cmt5: addw $4, %si # Skip entry
1005 jmp cmt1
1006
1007cmt2:
1008#endif /* CONFIG_VIDEO_COMPACT */
1009
1010 movw $ASK_VGA, (%di) # End marker
1011 movw %di, mt_end
1012mtab1: leaw modelist, %si # SI=mode list, DI=list end
1013ret0: ret
1014
1015# Modes usable on all standard VGAs
1016vga_modes:
1017 .word VIDEO_8POINT
1018 .word 0x5032 # 80x50
1019 .word VIDEO_80x43
1020 .word 0x502b # 80x43
1021 .word VIDEO_80x28
1022 .word 0x501c # 80x28
1023 .word VIDEO_80x30
1024 .word 0x501e # 80x30
1025 .word VIDEO_80x34
1026 .word 0x5022 # 80x34
1027 .word VIDEO_80x60
1028 .word 0x503c # 80x60
1029#ifdef CONFIG_VIDEO_GFX_HACK
1030 .word VIDEO_GFX_HACK
1031 .word VIDEO_GFX_DUMMY_RESOLUTION
1032#endif
1033
1034vga_modes_end:
1035# Detect VESA modes.
1036
1037#ifdef CONFIG_VIDEO_VESA
1038vesa_modes:
1039 cmpb $2, adapter # VGA only
1040 jnz ret0
1041
1042 movw %di, %bp # BP=original mode table end
1043 addw $0x200, %di # Buffer space
1044 movw $0x4f00, %ax # VESA Get card info call
1045 int $0x10
1046 movw %bp, %di
1047 cmpw $0x004f, %ax # Successful?
1048 jnz ret0
1049
1050 cmpw $0x4556, 0x200(%di)
1051 jnz ret0
1052
1053 cmpw $0x4153, 0x202(%di)
1054 jnz ret0
1055
1056 movw $vesa_name, card_name # Set name to "VESA VGA"
1057 pushw %gs
1058 lgsw 0x20e(%di), %si # GS:SI=mode list
1059 movw $128, %cx # Iteration limit
1060vesa1:
1061# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
1062# XXX: lodsw %gs:(%si), %ax # Get next mode in the list
1063 gs; lodsw
1064 cmpw $0xffff, %ax # End of the table?
1065 jz vesar
1066
1067 cmpw $0x0080, %ax # Check validity of mode ID
1068 jc vesa2
1069
1070 orb %ah, %ah # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
1071 jz vesan # Certain BIOSes report 0x80-0xff!
1072
1073 cmpw $0x0800, %ax
1074 jnc vesae
1075
1076vesa2: pushw %cx
1077 movw %ax, %cx # Get mode information structure
1078 movw $0x4f01, %ax
1079 int $0x10
1080 movw %cx, %bx # BX=mode number
1081 addb $VIDEO_FIRST_VESA>>8, %bh
1082 popw %cx
1083 cmpw $0x004f, %ax
1084 jnz vesan # Don't report errors (buggy BIOSES)
1085
1086 movb (%di), %al # Check capabilities. We require
1087 andb $0x19, %al # a color text mode.
1088 cmpb $0x09, %al
1089 jnz vesan
1090
1091 cmpw $0xb800, 8(%di) # Standard video memory address required
1092 jnz vesan
1093
1094 testb $2, (%di) # Mode characteristics supplied?
1095 movw %bx, (%di) # Store mode number
1096 jz vesa3
1097
1098 xorw %dx, %dx
1099 movw 0x12(%di), %bx # Width
1100 orb %bh, %bh
1101 jnz vesan
1102
1103 movb %bl, 0x3(%di)
1104 movw 0x14(%di), %ax # Height
1105 orb %ah, %ah
1106 jnz vesan
1107
1108 movb %al, 2(%di)
1109 mulb %bl
1110 cmpw $8193, %ax # Small enough for Linux console driver?
1111 jnc vesan
1112
1113 jmp vesaok
1114
1115vesa3: subw $0x8108, %bx # This mode has no detailed info specified,
1116 jc vesan # so it must be a standard VESA mode.
1117
1118 cmpw $5, %bx
1119 jnc vesan
1120
1121 movw vesa_text_mode_table(%bx), %ax
1122 movw %ax, 2(%di)
1123vesaok: addw $4, %di # The mode is valid. Store it.
1124vesan: loop vesa1 # Next mode. Limit exceeded => error
1125vesae: leaw vesaer, %si
1126 call prtstr
1127 movw %bp, %di # Discard already found modes.
1128vesar: popw %gs
1129 ret
1130
1131# Dimensions of standard VESA text modes
1132vesa_text_mode_table:
1133 .byte 60, 80 # 0108
1134 .byte 25, 132 # 0109
1135 .byte 43, 132 # 010A
1136 .byte 50, 132 # 010B
1137 .byte 60, 132 # 010C
1138#endif /* CONFIG_VIDEO_VESA */
1139
1140# Scan for video modes. A bit dirty, but should work.
1141mode_scan:
1142 movw $0x0100, %cx # Start with mode 0
1143scm1: movb $0, %ah # Test the mode
1144 movb %cl, %al
1145 int $0x10
1146 movb $0x0f, %ah
1147 int $0x10
1148 cmpb %cl, %al
1149 jnz scm2 # Mode not set
1150
1151 movw $0x3c0, %dx # Test if it's a text mode
1152 movb $0x10, %al # Mode bits
1153 call inidx
1154 andb $0x03, %al
1155 jnz scm2
1156
1157 movb $0xce, %dl # Another set of mode bits
1158 movb $0x06, %al
1159 call inidx
1160 shrb %al
1161 jc scm2
1162
1163 movb $0xd4, %dl # Cursor location
1164 movb $0x0f, %al
1165 call inidx
1166 orb %al, %al
1167 jnz scm2
1168
1169 movw %cx, %ax # Ok, store the mode
1170 stosw
1171 movb %gs:(0x484), %al # Number of rows
1172 incb %al
1173 stosb
1174 movw %gs:(0x44a), %ax # Number of columns
1175 stosb
1176scm2: incb %cl
1177 jns scm1
1178
1179 movw $0x0003, %ax # Return back to mode 3
1180 int $0x10
1181 ret
1182
1183tstidx: outw %ax, %dx # OUT DX,AX and inidx
1184inidx: outb %al, %dx # Read from indexed VGA register
1185 incw %dx # AL=index, DX=index reg port -> AL=data
1186 inb %dx, %al
1187 decw %dx
1188 ret
1189
1190# Try to detect type of SVGA card and supply (usually approximate) video
1191# mode table for it.
1192
1193#ifdef CONFIG_VIDEO_SVGA
1194svga_modes:
1195 leaw svga_table, %si # Test all known SVGA adapters
1196dosvga: lodsw
1197 movw %ax, %bp # Default mode table
1198 orw %ax, %ax
1199 jz didsv1
1200
1201 lodsw # Pointer to test routine
1202 pushw %si
1203 pushw %di
1204 pushw %es
1205 movw $0xc000, %bx
1206 movw %bx, %es
1207 call *%ax # Call test routine
1208 popw %es
1209 popw %di
1210 popw %si
1211 orw %bp, %bp
1212 jz dosvga
1213
1214 movw %bp, %si # Found, copy the modes
1215 movb svga_prefix, %ah
1216cpsvga: lodsb
1217 orb %al, %al
1218 jz didsv
1219
1220 stosw
1221 movsw
1222 jmp cpsvga
1223
1224didsv: movw %si, card_name # Store pointer to card name
1225didsv1: ret
1226
1227# Table of all known SVGA cards. For each card, we store a pointer to
1228# a table of video modes supported by the card and a pointer to a routine
1229# used for testing of presence of the card. The video mode table is always
1230# followed by the name of the card or the chipset.
1231svga_table:
1232 .word ati_md, ati_test
1233 .word oak_md, oak_test
1234 .word paradise_md, paradise_test
1235 .word realtek_md, realtek_test
1236 .word s3_md, s3_test
1237 .word chips_md, chips_test
1238 .word video7_md, video7_test
1239 .word cirrus5_md, cirrus5_test
1240 .word cirrus6_md, cirrus6_test
1241 .word cirrus1_md, cirrus1_test
1242 .word ahead_md, ahead_test
1243 .word everex_md, everex_test
1244 .word genoa_md, genoa_test
1245 .word trident_md, trident_test
1246 .word tseng_md, tseng_test
1247 .word 0
1248
1249# Test routines and mode tables:
1250
1251# S3 - The test algorithm was taken from the SuperProbe package
1252# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
1253s3_test:
1254 movw $0x0f35, %cx # we store some constants in cl/ch
1255 movw $0x03d4, %dx
1256 movb $0x38, %al
1257 call inidx
1258 movb %al, %bh # store current CRT-register 0x38
1259 movw $0x0038, %ax
1260 call outidx # disable writing to special regs
1261 movb %cl, %al # check whether we can write special reg 0x35
1262 call inidx
1263 movb %al, %bl # save the current value of CRT reg 0x35
1264 andb $0xf0, %al # clear bits 0-3
1265 movb %al, %ah
1266 movb %cl, %al # and write it to CRT reg 0x35
1267 call outidx
1268 call inidx # now read it back
1269 andb %ch, %al # clear the upper 4 bits
1270 jz s3_2 # the first test failed. But we have a
1271
1272 movb %bl, %ah # second chance
1273 movb %cl, %al
1274 call outidx
1275 jmp s3_1 # do the other tests
1276
1277s3_2: movw %cx, %ax # load ah with 0xf and al with 0x35
1278 orb %bl, %ah # set the upper 4 bits of ah with the orig value
1279 call outidx # write ...
1280 call inidx # ... and reread
1281 andb %cl, %al # turn off the upper 4 bits
1282 pushw %ax
1283 movb %bl, %ah # restore old value in register 0x35
1284 movb %cl, %al
1285 call outidx
1286 popw %ax
1287 cmpb %ch, %al # setting lower 4 bits was successful => bad
1288 je no_s3 # writing is allowed => this is not an S3
1289
1290s3_1: movw $0x4838, %ax # allow writing to special regs by putting
1291 call outidx # magic number into CRT-register 0x38
1292 movb %cl, %al # check whether we can write special reg 0x35
1293 call inidx
1294 movb %al, %bl
1295 andb $0xf0, %al
1296 movb %al, %ah
1297 movb %cl, %al
1298 call outidx
1299 call inidx
1300 andb %ch, %al
1301 jnz no_s3 # no, we can't write => no S3
1302
1303 movw %cx, %ax
1304 orb %bl, %ah
1305 call outidx
1306 call inidx
1307 andb %ch, %al
1308 pushw %ax
1309 movb %bl, %ah # restore old value in register 0x35
1310 movb %cl, %al
1311 call outidx
1312 popw %ax
1313 cmpb %ch, %al
1314 jne no_s31 # writing not possible => no S3
1315 movb $0x30, %al
1316 call inidx # now get the S3 id ...
1317 leaw idS3, %di
1318 movw $0x10, %cx
1319 repne
1320 scasb
1321 je no_s31
1322
1323 movb %bh, %ah
1324 movb $0x38, %al
1325 jmp s3rest
1326
1327no_s3: movb $0x35, %al # restore CRT register 0x35
1328 movb %bl, %ah
1329 call outidx
1330no_s31: xorw %bp, %bp # Detection failed
1331s3rest: movb %bh, %ah
1332 movb $0x38, %al # restore old value of CRT register 0x38
1333 jmp outidx
1334
1335idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
1336 .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
1337
1338s3_md: .byte 0x54, 0x2b, 0x84
1339 .byte 0x55, 0x19, 0x84
1340 .byte 0
1341 .ascii "S3"
1342 .byte 0
1343
1344# ATI cards.
1345ati_test:
1346 leaw idati, %si
1347 movw $0x31, %di
1348 movw $0x09, %cx
1349 repe
1350 cmpsb
1351 je atiok
1352
1353 xorw %bp, %bp
1354atiok: ret
1355
1356idati: .ascii "761295520"
1357
1358ati_md: .byte 0x23, 0x19, 0x84
1359 .byte 0x33, 0x2c, 0x84
1360 .byte 0x22, 0x1e, 0x64
1361 .byte 0x21, 0x19, 0x64
1362 .byte 0x58, 0x21, 0x50
1363 .byte 0x5b, 0x1e, 0x50
1364 .byte 0
1365 .ascii "ATI"
1366 .byte 0
1367
1368# AHEAD
1369ahead_test:
1370 movw $0x200f, %ax
1371 movw $0x3ce, %dx
1372 outw %ax, %dx
1373 incw %dx
1374 inb %dx, %al
1375 cmpb $0x20, %al
1376 je isahed
1377
1378 cmpb $0x21, %al
1379 je isahed
1380
1381 xorw %bp, %bp
1382isahed: ret
1383
1384ahead_md:
1385 .byte 0x22, 0x2c, 0x84
1386 .byte 0x23, 0x19, 0x84
1387 .byte 0x24, 0x1c, 0x84
1388 .byte 0x2f, 0x32, 0xa0
1389 .byte 0x32, 0x22, 0x50
1390 .byte 0x34, 0x42, 0x50
1391 .byte 0
1392 .ascii "Ahead"
1393 .byte 0
1394
1395# Chips & Tech.
1396chips_test:
1397 movw $0x3c3, %dx
1398 inb %dx, %al
1399 orb $0x10, %al
1400 outb %al, %dx
1401 movw $0x104, %dx
1402 inb %dx, %al
1403 movb %al, %bl
1404 movw $0x3c3, %dx
1405 inb %dx, %al
1406 andb $0xef, %al
1407 outb %al, %dx
1408 cmpb $0xa5, %bl
1409 je cantok
1410
1411 xorw %bp, %bp
1412cantok: ret
1413
1414chips_md:
1415 .byte 0x60, 0x19, 0x84
1416 .byte 0x61, 0x32, 0x84
1417 .byte 0
1418 .ascii "Chips & Technologies"
1419 .byte 0
1420
1421# Cirrus Logic 5X0
1422cirrus1_test:
1423 movw $0x3d4, %dx
1424 movb $0x0c, %al
1425 outb %al, %dx
1426 incw %dx
1427 inb %dx, %al
1428 movb %al, %bl
1429 xorb %al, %al
1430 outb %al, %dx
1431 decw %dx
1432 movb $0x1f, %al
1433 outb %al, %dx
1434 incw %dx
1435 inb %dx, %al
1436 movb %al, %bh
1437 xorb %ah, %ah
1438 shlb $4, %al
1439 movw %ax, %cx
1440 movb %bh, %al
1441 shrb $4, %al
1442 addw %ax, %cx
1443 shlw $8, %cx
1444 addw $6, %cx
1445 movw %cx, %ax
1446 movw $0x3c4, %dx
1447 outw %ax, %dx
1448 incw %dx
1449 inb %dx, %al
1450 andb %al, %al
1451 jnz nocirr
1452
1453 movb %bh, %al
1454 outb %al, %dx
1455 inb %dx, %al
1456 cmpb $0x01, %al
1457 je iscirr
1458
1459nocirr: xorw %bp, %bp
1460iscirr: movw $0x3d4, %dx
1461 movb %bl, %al
1462 xorb %ah, %ah
1463 shlw $8, %ax
1464 addw $0x0c, %ax
1465 outw %ax, %dx
1466 ret
1467
1468cirrus1_md:
1469 .byte 0x1f, 0x19, 0x84
1470 .byte 0x20, 0x2c, 0x84
1471 .byte 0x22, 0x1e, 0x84
1472 .byte 0x31, 0x25, 0x64
1473 .byte 0
1474 .ascii "Cirrus Logic 5X0"
1475 .byte 0
1476
1477# Cirrus Logic 54XX
1478cirrus5_test:
1479 movw $0x3c4, %dx
1480 movb $6, %al
1481 call inidx
1482 movb %al, %bl # BL=backup
1483 movw $6, %ax
1484 call tstidx
1485 cmpb $0x0f, %al
1486 jne c5fail
1487
1488 movw $0x1206, %ax
1489 call tstidx
1490 cmpb $0x12, %al
1491 jne c5fail
1492
1493 movb $0x1e, %al
1494 call inidx
1495 movb %al, %bh
1496 movb %bh, %ah
1497 andb $0xc0, %ah
1498 movb $0x1e, %al
1499 call tstidx
1500 andb $0x3f, %al
1501 jne c5xx
1502
1503 movb $0x1e, %al
1504 movb %bh, %ah
1505 orb $0x3f, %ah
1506 call tstidx
1507 xorb $0x3f, %al
1508 andb $0x3f, %al
1509c5xx: pushf
1510 movb $0x1e, %al
1511 movb %bh, %ah
1512 outw %ax, %dx
1513 popf
1514 je c5done
1515
1516c5fail: xorw %bp, %bp
1517c5done: movb $6, %al
1518 movb %bl, %ah
1519 outw %ax, %dx
1520 ret
1521
1522cirrus5_md:
1523 .byte 0x14, 0x19, 0x84
1524 .byte 0x54, 0x2b, 0x84
1525 .byte 0
1526 .ascii "Cirrus Logic 54XX"
1527 .byte 0
1528
1529# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
1530# it's misidentified by the Ahead test.
1531cirrus6_test:
1532 movw $0x3ce, %dx
1533 movb $0x0a, %al
1534 call inidx
1535 movb %al, %bl # BL=backup
1536 movw $0xce0a, %ax
1537 call tstidx
1538 orb %al, %al
1539 jne c2fail
1540
1541 movw $0xec0a, %ax
1542 call tstidx
1543 cmpb $0x01, %al
1544 jne c2fail
1545
1546 movb $0xaa, %al
1547 call inidx # 4X, 5X, 7X and 8X are valid 64XX chip ID's.
1548 shrb $4, %al
1549 subb $4, %al
1550 jz c6done
1551
1552 decb %al
1553 jz c6done
1554
1555 subb $2, %al
1556 jz c6done
1557
1558 decb %al
1559 jz c6done
1560
1561c2fail: xorw %bp, %bp
1562c6done: movb $0x0a, %al
1563 movb %bl, %ah
1564 outw %ax, %dx
1565 ret
1566
1567cirrus6_md:
1568 .byte 0
1569 .ascii "Cirrus Logic 64XX"
1570 .byte 0
1571
1572# Everex / Trident
1573everex_test:
1574 movw $0x7000, %ax
1575 xorw %bx, %bx
1576 int $0x10
1577 cmpb $0x70, %al
1578 jne noevrx
1579
1580 shrw $4, %dx
1581 cmpw $0x678, %dx
1582 je evtrid
1583
1584 cmpw $0x236, %dx
1585 jne evrxok
1586
1587evtrid: leaw trident_md, %bp
1588evrxok: ret
1589
1590noevrx: xorw %bp, %bp
1591 ret
1592
1593everex_md:
1594 .byte 0x03, 0x22, 0x50
1595 .byte 0x04, 0x3c, 0x50
1596 .byte 0x07, 0x2b, 0x64
1597 .byte 0x08, 0x4b, 0x64
1598 .byte 0x0a, 0x19, 0x84
1599 .byte 0x0b, 0x2c, 0x84
1600 .byte 0x16, 0x1e, 0x50
1601 .byte 0x18, 0x1b, 0x64
1602 .byte 0x21, 0x40, 0xa0
1603 .byte 0x40, 0x1e, 0x84
1604 .byte 0
1605 .ascii "Everex/Trident"
1606 .byte 0
1607
1608# Genoa.
1609genoa_test:
1610 leaw idgenoa, %si # Check Genoa 'clues'
1611 xorw %ax, %ax
1612 movb %es:(0x37), %al
1613 movw %ax, %di
1614 movw $0x04, %cx
1615 decw %si
1616 decw %di
1617l1: incw %si
1618 incw %di
1619 movb (%si), %al
1620 testb %al, %al
1621 jz l2
1622
1623 cmpb %es:(%di), %al
1624l2: loope l1
1625 orw %cx, %cx
1626 je isgen
1627
1628 xorw %bp, %bp
1629isgen: ret
1630
1631idgenoa: .byte 0x77, 0x00, 0x99, 0x66
1632
1633genoa_md:
1634 .byte 0x58, 0x20, 0x50
1635 .byte 0x5a, 0x2a, 0x64
1636 .byte 0x60, 0x19, 0x84
1637 .byte 0x61, 0x1d, 0x84
1638 .byte 0x62, 0x20, 0x84
1639 .byte 0x63, 0x2c, 0x84
1640 .byte 0x64, 0x3c, 0x84
1641 .byte 0x6b, 0x4f, 0x64
1642 .byte 0x72, 0x3c, 0x50
1643 .byte 0x74, 0x42, 0x50
1644 .byte 0x78, 0x4b, 0x64
1645 .byte 0
1646 .ascii "Genoa"
1647 .byte 0
1648
1649# OAK
1650oak_test:
1651 leaw idoakvga, %si
1652 movw $0x08, %di
1653 movw $0x08, %cx
1654 repe
1655 cmpsb
1656 je isoak
1657
1658 xorw %bp, %bp
1659isoak: ret
1660
1661idoakvga: .ascii "OAK VGA "
1662
1663oak_md: .byte 0x4e, 0x3c, 0x50
1664 .byte 0x4f, 0x3c, 0x84
1665 .byte 0x50, 0x19, 0x84
1666 .byte 0x51, 0x2b, 0x84
1667 .byte 0
1668 .ascii "OAK"
1669 .byte 0
1670
1671# WD Paradise.
1672paradise_test:
1673 leaw idparadise, %si
1674 movw $0x7d, %di
1675 movw $0x04, %cx
1676 repe
1677 cmpsb
1678 je ispara
1679
1680 xorw %bp, %bp
1681ispara: ret
1682
1683idparadise: .ascii "VGA="
1684
1685paradise_md:
1686 .byte 0x41, 0x22, 0x50
1687 .byte 0x47, 0x1c, 0x84
1688 .byte 0x55, 0x19, 0x84
1689 .byte 0x54, 0x2c, 0x84
1690 .byte 0
1691 .ascii "Paradise"
1692 .byte 0
1693
1694# Trident.
1695trident_test:
1696 movw $0x3c4, %dx
1697 movb $0x0e, %al
1698 outb %al, %dx
1699 incw %dx
1700 inb %dx, %al
1701 xchgb %al, %ah
1702 xorb %al, %al
1703 outb %al, %dx
1704 inb %dx, %al
1705 xchgb %ah, %al
1706 movb %al, %bl # Strange thing ... in the book this wasn't
1707 andb $0x02, %bl # necessary but it worked on my card which
1708 jz setb2 # is a trident. Without it the screen goes
1709 # blurred ...
1710 andb $0xfd, %al
1711 jmp clrb2
1712
1713setb2: orb $0x02, %al
1714clrb2: outb %al, %dx
1715 andb $0x0f, %ah
1716 cmpb $0x02, %ah
1717 je istrid
1718
1719 xorw %bp, %bp
1720istrid: ret
1721
1722trident_md:
1723 .byte 0x50, 0x1e, 0x50
1724 .byte 0x51, 0x2b, 0x50
1725 .byte 0x52, 0x3c, 0x50
1726 .byte 0x57, 0x19, 0x84
1727 .byte 0x58, 0x1e, 0x84
1728 .byte 0x59, 0x2b, 0x84
1729 .byte 0x5a, 0x3c, 0x84
1730 .byte 0
1731 .ascii "Trident"
1732 .byte 0
1733
1734# Tseng.
1735tseng_test:
1736 movw $0x3cd, %dx
1737 inb %dx, %al # Could things be this simple ! :-)
1738 movb %al, %bl
1739 movb $0x55, %al
1740 outb %al, %dx
1741 inb %dx, %al
1742 movb %al, %ah
1743 movb %bl, %al
1744 outb %al, %dx
1745 cmpb $0x55, %ah
1746 je istsen
1747
1748isnot: xorw %bp, %bp
1749istsen: ret
1750
1751tseng_md:
1752 .byte 0x26, 0x3c, 0x50
1753 .byte 0x2a, 0x28, 0x64
1754 .byte 0x23, 0x19, 0x84
1755 .byte 0x24, 0x1c, 0x84
1756 .byte 0x22, 0x2c, 0x84
1757 .byte 0x21, 0x3c, 0x84
1758 .byte 0
1759 .ascii "Tseng"
1760 .byte 0
1761
1762# Video7.
1763video7_test:
1764 movw $0x3cc, %dx
1765 inb %dx, %al
1766 movw $0x3b4, %dx
1767 andb $0x01, %al
1768 jz even7
1769
1770 movw $0x3d4, %dx
1771even7: movb $0x0c, %al
1772 outb %al, %dx
1773 incw %dx
1774 inb %dx, %al
1775 movb %al, %bl
1776 movb $0x55, %al
1777 outb %al, %dx
1778 inb %dx, %al
1779 decw %dx
1780 movb $0x1f, %al
1781 outb %al, %dx
1782 incw %dx
1783 inb %dx, %al
1784 movb %al, %bh
1785 decw %dx
1786 movb $0x0c, %al
1787 outb %al, %dx
1788 incw %dx
1789 movb %bl, %al
1790 outb %al, %dx
1791 movb $0x55, %al
1792 xorb $0xea, %al
1793 cmpb %bh, %al
1794 jne isnot
1795
1796 movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
1797 ret
1798
1799video7_md:
1800 .byte 0x40, 0x2b, 0x50
1801 .byte 0x43, 0x3c, 0x50
1802 .byte 0x44, 0x3c, 0x64
1803 .byte 0x41, 0x19, 0x84
1804 .byte 0x42, 0x2c, 0x84
1805 .byte 0x45, 0x1c, 0x84
1806 .byte 0
1807 .ascii "Video 7"
1808 .byte 0
1809
1810# Realtek VGA
1811realtek_test:
1812 leaw idrtvga, %si
1813 movw $0x45, %di
1814 movw $0x0b, %cx
1815 repe
1816 cmpsb
1817 je isrt
1818
1819 xorw %bp, %bp
1820isrt: ret
1821
1822idrtvga: .ascii "REALTEK VGA"
1823
1824realtek_md:
1825 .byte 0x1a, 0x3c, 0x50
1826 .byte 0x1b, 0x19, 0x84
1827 .byte 0x1c, 0x1e, 0x84
1828 .byte 0x1d, 0x2b, 0x84
1829 .byte 0x1e, 0x3c, 0x84
1830 .byte 0
1831 .ascii "REALTEK"
1832 .byte 0
1833
1834#endif /* CONFIG_VIDEO_SVGA */
1835
1836# User-defined local mode table (VGA only)
1837#ifdef CONFIG_VIDEO_LOCAL
1838local_modes:
1839 leaw local_mode_table, %si
1840locm1: lodsw
1841 orw %ax, %ax
1842 jz locm2
1843
1844 stosw
1845 movsw
1846 jmp locm1
1847
1848locm2: ret
1849
1850# This is the table of local video modes which can be supplied manually
1851# by the user. Each entry consists of mode ID (word) and dimensions
1852# (byte for column count and another byte for row count). These modes
1853# are placed before all SVGA and VESA modes and override them if table
1854# compacting is enabled. The table must end with a zero word followed
1855# by NUL-terminated video adapter name.
1856local_mode_table:
1857 .word 0x0100 # Example: 40x25
1858 .byte 25,40
1859 .word 0
1860 .ascii "Local"
1861 .byte 0
1862#endif /* CONFIG_VIDEO_LOCAL */
1863
1864# Read a key and return the ASCII code in al, scan code in ah
1865getkey: xorb %ah, %ah
1866 int $0x16
1867 ret
1868
1869# Read a key with a timeout of 30 seconds.
1870# The hardware clock is used to get the time.
1871getkt: call gettime
1872 addb $30, %al # Wait 30 seconds
1873 cmpb $60, %al
1874 jl lminute
1875
1876 subb $60, %al
1877lminute:
1878 movb %al, %cl
1879again: movb $0x01, %ah
1880 int $0x16
1881 jnz getkey # key pressed, so get it
1882
1883 call gettime
1884 cmpb %cl, %al
1885 jne again
1886
1887 movb $0x20, %al # timeout, return `space'
1888 ret
1889
1890# Flush the keyboard buffer
1891flush: movb $0x01, %ah
1892 int $0x16
1893 jz empty
1894
1895 xorb %ah, %ah
1896 int $0x16
1897 jmp flush
1898
1899empty: ret
1900
1901# Print hexadecimal number.
1902prthw: pushw %ax
1903 movb %ah, %al
1904 call prthb
1905 popw %ax
1906prthb: pushw %ax
1907 shrb $4, %al
1908 call prthn
1909 popw %ax
1910 andb $0x0f, %al
1911prthn: cmpb $0x0a, %al
1912 jc prth1
1913
1914 addb $0x07, %al
1915prth1: addb $0x30, %al
1916 jmp prtchr
1917
1918# Print decimal number in al
1919prtdec: pushw %ax
1920 pushw %cx
1921 xorb %ah, %ah
1922 movb $0x0a, %cl
1923 idivb %cl
1924 cmpb $0x09, %al
1925 jbe lt100
1926
1927 call prtdec
1928 jmp skip10
1929
1930lt100: addb $0x30, %al
1931 call prtchr
1932skip10: movb %ah, %al
1933 addb $0x30, %al
1934 call prtchr
1935 popw %cx
1936 popw %ax
1937 ret
1938
1939store_edid:
1940#ifdef CONFIG_FIRMWARE_EDID
1941 pushw %es # just save all registers
1942 pushw %ax
1943 pushw %bx
1944 pushw %cx
1945 pushw %dx
1946 pushw %di
1947
1948 pushw %fs
1949 popw %es
1950
1951 movl $0x13131313, %eax # memset block with 0x13
1952 movw $32, %cx
1953 movw $0x140, %di
1954 cld
1955 rep
1956 stosl
1957
1958 cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0
1959 jl no_edid
1960
1961 pushw %es # save ES
1962 xorw %di, %di # Report Capability
1963 pushw %di
1964 popw %es # ES:DI must be 0:0
1965 movw $0x4f15, %ax
1966 xorw %bx, %bx
1967 xorw %cx, %cx
1968 int $0x10
1969 popw %es # restore ES
1970
1971 cmpb $0x00, %ah # call successful
1972 jne no_edid
1973
1974 cmpb $0x4f, %al # function supported
1975 jne no_edid
1976
1977 movw $0x4f15, %ax # do VBE/DDC
1978 movw $0x01, %bx
1979 movw $0x00, %cx
1980 movw $0x00, %dx
1981 movw $0x140, %di
1982 int $0x10
1983
1984no_edid:
1985 popw %di # restore all registers
1986 popw %dx
1987 popw %cx
1988 popw %bx
1989 popw %ax
1990 popw %es
1991#endif
1992 ret
1993
1994# VIDEO_SELECT-only variables
1995mt_end: .word 0 # End of video mode table if built
1996edit_buf: .space 6 # Line editor buffer
1997card_name: .word 0 # Pointer to adapter name
1998scanning: .byte 0 # Performing mode scan
1999do_restore: .byte 0 # Screen contents altered during mode change
2000svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes
2001graphic_mode: .byte 0 # Graphic mode with a linear frame buffer
2002dac_size: .byte 6 # DAC bit depth
2003vbe_version: .word 0 # VBE bios version
2004
2005# Status messages
2006keymsg: .ascii "Press <RETURN> to see video modes available, "
2007 .ascii "<SPACE> to continue or wait 30 secs"
2008 .byte 0x0d, 0x0a, 0
2009
2010listhdr: .byte 0x0d, 0x0a
2011 .ascii "Mode: COLSxROWS:"
2012
2013crlft: .byte 0x0d, 0x0a, 0
2014
2015prompt: .byte 0x0d, 0x0a
2016 .asciz "Enter mode number or `scan': "
2017
2018unknt: .asciz "Unknown mode ID. Try again."
2019
2020badmdt: .ascii "You passed an undefined mode number."
2021 .byte 0x0d, 0x0a, 0
2022
2023vesaer: .ascii "Error: Scanning of VESA modes failed. Please "
2024 .ascii "report to <mj@ucw.cz>."
2025 .byte 0x0d, 0x0a, 0
2026
2027old_name: .asciz "CGA/MDA/HGA"
2028
2029ega_name: .asciz "EGA"
2030
2031svga_name: .ascii " "
2032
2033vga_name: .asciz "VGA"
2034
2035vesa_name: .asciz "VESA"
2036
2037name_bann: .asciz "Video adapter: "
2038#endif /* CONFIG_VIDEO_SELECT */
2039
2040# Other variables:
2041adapter: .byte 0 # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
2042video_segment: .word 0xb800 # Video memory segment
2043force_size: .word 0 # Use this size instead of the one in BIOS vars
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c
new file mode 100644
index 000000000000..3bb3573cd6a1
--- /dev/null
+++ b/arch/i386/boot/video.c
@@ -0,0 +1,456 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/video.c
13 *
14 * Select video mode
15 */
16
17#include "boot.h"
18#include "video.h"
19#include "vesa.h"
20
21/*
22 * Mode list variables
23 */
24static struct card_info cards[]; /* List of cards to probe for */
25
26/*
27 * Common variables
28 */
29int adapter; /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
30u16 video_segment;
31int force_x, force_y; /* Don't query the BIOS for cols/rows */
32
33int do_restore = 0; /* Screen contents changed during mode flip */
34int graphic_mode; /* Graphic mode with linear frame buffer */
35
36static void store_cursor_position(void)
37{
38 u16 curpos;
39 u16 ax, bx;
40
41 ax = 0x0300;
42 bx = 0;
43 asm(INT10
44 : "=d" (curpos), "+a" (ax), "+b" (bx)
45 : : "ecx", "esi", "edi");
46
47 boot_params.screen_info.orig_x = curpos;
48 boot_params.screen_info.orig_y = curpos >> 8;
49}
50
51static void store_video_mode(void)
52{
53 u16 ax, page;
54
55 /* N.B.: the saving of the video page here is a bit silly,
56 since we pretty much assume page 0 everywhere. */
57 ax = 0x0f00;
58 asm(INT10
59 : "+a" (ax), "=b" (page)
60 : : "ecx", "edx", "esi", "edi");
61
62 /* Not all BIOSes are clean with respect to the top bit */
63 boot_params.screen_info.orig_video_mode = ax & 0x7f;
64 boot_params.screen_info.orig_video_page = page;
65}
66
67/*
68 * Store the video mode parameters for later usage by the kernel.
69 * This is done by asking the BIOS except for the rows/columns
70 * parameters in the default 80x25 mode -- these are set directly,
71 * because some very obscure BIOSes supply insane values.
72 */
73static void store_mode_params(void)
74{
75 u16 font_size;
76 int x, y;
77
78 /* For graphics mode, it is up to the mode-setting driver
79 (currently only video-vesa.c) to store the parameters */
80 if (graphic_mode)
81 return;
82
83 store_cursor_position();
84 store_video_mode();
85
86 if (boot_params.screen_info.orig_video_mode == 0x07) {
87 /* MDA, HGC, or VGA in monochrome mode */
88 video_segment = 0xb000;
89 } else {
90 /* CGA, EGA, VGA and so forth */
91 video_segment = 0xb800;
92 }
93
94 set_fs(0);
95 font_size = rdfs16(0x485); /* Font size, BIOS area */
96 boot_params.screen_info.orig_video_points = font_size;
97
98 x = rdfs16(0x44a);
99 y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
100
101 if (force_x)
102 x = force_x;
103 if (force_y)
104 y = force_y;
105
106 boot_params.screen_info.orig_video_cols = x;
107 boot_params.screen_info.orig_video_lines = y;
108}
109
110/* Probe the video drivers and have them generate their mode lists. */
111static void probe_cards(int unsafe)
112{
113 struct card_info *card;
114 static u8 probed[2];
115
116 if (probed[unsafe])
117 return;
118
119 probed[unsafe] = 1;
120
121 for (card = video_cards; card < video_cards_end; card++) {
122 if (card->unsafe == unsafe) {
123 if (card->probe)
124 card->nmodes = card->probe();
125 else
126 card->nmodes = 0;
127 }
128 }
129}
130
131/* Test if a mode is defined */
132int mode_defined(u16 mode)
133{
134 struct card_info *card;
135 struct mode_info *mi;
136 int i;
137
138 for (card = video_cards; card < video_cards_end; card++) {
139 mi = card->modes;
140 for (i = 0; i < card->nmodes; i++, mi++) {
141 if (mi->mode == mode)
142 return 1;
143 }
144 }
145
146 return 0;
147}
148
149/* Set mode (without recalc) */
150static int raw_set_mode(u16 mode)
151{
152 int nmode, i;
153 struct card_info *card;
154 struct mode_info *mi;
155
156 /* Drop the recalc bit if set */
157 mode &= ~VIDEO_RECALC;
158
159 /* Scan for mode based on fixed ID, position, or resolution */
160 nmode = 0;
161 for (card = video_cards; card < video_cards_end; card++) {
162 mi = card->modes;
163 for (i = 0; i < card->nmodes; i++, mi++) {
164 int visible = mi->x || mi->y;
165
166 if ((mode == nmode && visible) ||
167 mode == mi->mode ||
168 mode == (mi->y << 8)+mi->x)
169 return card->set_mode(mi);
170
171 if (visible)
172 nmode++;
173 }
174 }
175
176 /* Nothing found? Is it an "exceptional" (unprobed) mode? */
177 for (card = video_cards; card < video_cards_end; card++) {
178 if (mode >= card->xmode_first &&
179 mode < card->xmode_first+card->xmode_n) {
180 struct mode_info mix;
181 mix.mode = mode;
182 mix.x = mix.y = 0;
183 return card->set_mode(&mix);
184 }
185 }
186
187 /* Otherwise, failure... */
188 return -1;
189}
190
191/*
192 * Recalculate the vertical video cutoff (hack!)
193 */
194static void vga_recalc_vertical(void)
195{
196 unsigned int font_size, rows;
197 u16 crtc;
198 u8 ov;
199
200 set_fs(0);
201 font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
202 rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
203
204 rows *= font_size; /* Visible scan lines */
205 rows--; /* ... minus one */
206
207 crtc = vga_crtc();
208
209 out_idx((u8)rows, crtc, 0x12); /* Lower height register */
210 ov = in_idx(crtc, 0x07); /* Overflow register */
211 ov &= 0xbd;
212 ov |= (rows >> (8-1)) & 0x02;
213 ov |= (rows >> (9-6)) & 0x40;
214 out_idx(ov, crtc, 0x07);
215}
216
217/* Set mode (with recalc if specified) */
218static int set_mode(u16 mode)
219{
220 int rv;
221
222 /* Very special mode numbers... */
223 if (mode == VIDEO_CURRENT_MODE)
224 return 0; /* Nothing to do... */
225 else if (mode == NORMAL_VGA)
226 mode = VIDEO_80x25;
227 else if (mode == EXTENDED_VGA)
228 mode = VIDEO_8POINT;
229
230 rv = raw_set_mode(mode);
231 if (rv)
232 return rv;
233
234 if (mode & VIDEO_RECALC)
235 vga_recalc_vertical();
236
237 return 0;
238}
239
240static unsigned int get_entry(void)
241{
242 char entry_buf[4];
243 int i, len = 0;
244 int key;
245 unsigned int v;
246
247 do {
248 key = getchar();
249
250 if (key == '\b') {
251 if (len > 0) {
252 puts("\b \b");
253 len--;
254 }
255 } else if ((key >= '0' && key <= '9') ||
256 (key >= 'A' && key <= 'Z') ||
257 (key >= 'a' && key <= 'z')) {
258 if (len < sizeof entry_buf) {
259 entry_buf[len++] = key;
260 putchar(key);
261 }
262 }
263 } while (key != '\r');
264 putchar('\n');
265
266 if (len == 0)
267 return VIDEO_CURRENT_MODE; /* Default */
268
269 v = 0;
270 for (i = 0; i < len; i++) {
271 v <<= 4;
272 key = entry_buf[i] | 0x20;
273 v += (key > '9') ? key-'a'+10 : key-'0';
274 }
275
276 return v;
277}
278
279static void display_menu(void)
280{
281 struct card_info *card;
282 struct mode_info *mi;
283 char ch;
284 int i;
285
286 puts("Mode: COLSxROWS:\n");
287
288 ch = '0';
289 for (card = video_cards; card < video_cards_end; card++) {
290 mi = card->modes;
291 for (i = 0; i < card->nmodes; i++, mi++) {
292 int visible = mi->x && mi->y;
293 u16 mode_id = mi->mode ? mi->mode :
294 (mi->y << 8)+mi->x;
295
296 if (!visible)
297 continue; /* Hidden mode */
298
299 printf("%c %04X %3dx%-3d %s\n",
300 ch, mode_id, mi->x, mi->y, card->card_name);
301
302 if (ch == '9')
303 ch = 'a';
304 else if (ch == 'z' || ch == ' ')
305 ch = ' '; /* Out of keys... */
306 else
307 ch++;
308 }
309 }
310}
311
312#define H(x) ((x)-'a'+10)
313#define SCAN ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
314
315static unsigned int mode_menu(void)
316{
317 int key;
318 unsigned int sel;
319
320 puts("Press <ENTER> to see video modes available, "
321 "<SPACE> to continue, or wait 30 sec\n");
322
323 kbd_flush();
324 while (1) {
325 key = getchar_timeout();
326 if (key == ' ' || key == 0)
327 return VIDEO_CURRENT_MODE; /* Default */
328 if (key == '\r')
329 break;
330 putchar('\a'); /* Beep! */
331 }
332
333
334 for (;;) {
335 display_menu();
336
337 puts("Enter a video mode or \"scan\" to scan for "
338 "additional modes: ");
339 sel = get_entry();
340 if (sel != SCAN)
341 return sel;
342
343 probe_cards(1);
344 }
345}
346
347#ifdef CONFIG_VIDEO_RETAIN
348/* Save screen content to the heap */
349struct saved_screen {
350 int x, y;
351 int curx, cury;
352 u16 *data;
353} saved;
354
355static void save_screen(void)
356{
357 /* Should be called after store_mode_params() */
358 saved.x = boot_params.screen_info.orig_video_cols;
359 saved.y = boot_params.screen_info.orig_video_lines;
360 saved.curx = boot_params.screen_info.orig_x;
361 saved.cury = boot_params.screen_info.orig_y;
362
363 if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
364 return; /* Not enough heap to save the screen */
365
366 saved.data = GET_HEAP(u16, saved.x*saved.y);
367
368 set_fs(video_segment);
369 copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
370}
371
372static void restore_screen(void)
373{
374 /* Should be called after store_mode_params() */
375 int xs = boot_params.screen_info.orig_video_cols;
376 int ys = boot_params.screen_info.orig_video_lines;
377 int y;
378 addr_t dst = 0;
379 u16 *src = saved.data;
380 u16 ax, bx, dx;
381
382 if (graphic_mode)
383 return; /* Can't restore onto a graphic mode */
384
385 if (!src)
386 return; /* No saved screen contents */
387
388 /* Restore screen contents */
389
390 set_fs(video_segment);
391 for (y = 0; y < ys; y++) {
392 int npad;
393
394 if (y < saved.y) {
395 int copy = (xs < saved.x) ? xs : saved.x;
396 copy_to_fs(dst, src, copy*sizeof(u16));
397 dst += copy*sizeof(u16);
398 src += saved.x;
399 npad = (xs < saved.x) ? 0 : xs-saved.x;
400 } else {
401 npad = xs;
402 }
403
404 /* Writes "npad" blank characters to
405 video_segment:dst and advances dst */
406 asm volatile("pushw %%es ; "
407 "movw %2,%%es ; "
408 "shrw %%cx ; "
409 "jnc 1f ; "
410 "stosw \n\t"
411 "1: rep;stosl ; "
412 "popw %%es"
413 : "+D" (dst), "+c" (npad)
414 : "bdSm" (video_segment),
415 "a" (0x07200720));
416 }
417
418 /* Restore cursor position */
419 ax = 0x0200; /* Set cursor position */
420 bx = 0; /* Page number (<< 8) */
421 dx = (saved.cury << 8)+saved.curx;
422 asm volatile(INT10
423 : "+a" (ax), "+b" (bx), "+d" (dx)
424 : : "ecx", "esi", "edi");
425}
426#else
427#define save_screen() ((void)0)
428#define restore_screen() ((void)0)
429#endif
430
431void set_video(void)
432{
433 u16 mode = boot_params.hdr.vid_mode;
434
435 RESET_HEAP();
436
437 store_mode_params();
438 save_screen();
439 probe_cards(0);
440
441 for (;;) {
442 if (mode == ASK_VGA)
443 mode = mode_menu();
444
445 if (!set_mode(mode))
446 break;
447
448 printf("Undefined video mode number: %x\n", mode);
449 mode = ASK_VGA;
450 }
451 vesa_store_edid();
452 store_mode_params();
453
454 if (do_restore)
455 restore_screen();
456}
diff --git a/arch/i386/boot/video.h b/arch/i386/boot/video.h
new file mode 100644
index 000000000000..29eca1710b2c
--- /dev/null
+++ b/arch/i386/boot/video.h
@@ -0,0 +1,145 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/video.h
13 *
14 * Header file for the real-mode video probing code
15 */
16
17#ifndef BOOT_VIDEO_H
18#define BOOT_VIDEO_H
19
20#include <linux/types.h>
21
22/* Enable autodetection of SVGA adapters and modes. */
23#undef CONFIG_VIDEO_SVGA
24
25/* Enable autodetection of VESA modes */
26#define CONFIG_VIDEO_VESA
27
28/* Retain screen contents when switching modes */
29#define CONFIG_VIDEO_RETAIN
30
31/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
32#undef CONFIG_VIDEO_400_HACK
33
34/* This code uses an extended set of video mode numbers. These include:
35 * Aliases for standard modes
36 * NORMAL_VGA (-1)
37 * EXTENDED_VGA (-2)
38 * ASK_VGA (-3)
39 * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
40 * of compatibility when extending the table. These are between 0x00 and 0xff.
41 */
42#define VIDEO_FIRST_MENU 0x0000
43
44/* Standard BIOS video modes (BIOS number + 0x0100) */
45#define VIDEO_FIRST_BIOS 0x0100
46
47/* VESA BIOS video modes (VESA number + 0x0200) */
48#define VIDEO_FIRST_VESA 0x0200
49
50/* Video7 special modes (BIOS number + 0x0900) */
51#define VIDEO_FIRST_V7 0x0900
52
53/* Special video modes */
54#define VIDEO_FIRST_SPECIAL 0x0f00
55#define VIDEO_80x25 0x0f00
56#define VIDEO_8POINT 0x0f01
57#define VIDEO_80x43 0x0f02
58#define VIDEO_80x28 0x0f03
59#define VIDEO_CURRENT_MODE 0x0f04
60#define VIDEO_80x30 0x0f05
61#define VIDEO_80x34 0x0f06
62#define VIDEO_80x60 0x0f07
63#define VIDEO_GFX_HACK 0x0f08
64#define VIDEO_LAST_SPECIAL 0x0f09
65
66/* Video modes given by resolution */
67#define VIDEO_FIRST_RESOLUTION 0x1000
68
69/* The "recalculate timings" flag */
70#define VIDEO_RECALC 0x8000
71
72/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
73#ifdef CONFIG_VIDEO_RETAIN
74void store_screen(void);
75#define DO_STORE() store_screen()
76#else
77#define DO_STORE() ((void)0)
78#endif /* CONFIG_VIDEO_RETAIN */
79
80/*
81 * Mode table structures
82 */
83
84struct mode_info {
85 u16 mode; /* Mode number (vga= style) */
86 u8 x, y; /* Width, height */
87};
88
89struct card_info {
90 const char *card_name;
91 int (*set_mode)(struct mode_info *mode);
92 int (*probe)(void);
93 struct mode_info *modes;
94 int nmodes; /* Number of probed modes so far */
95 int unsafe; /* Probing is unsafe, only do after "scan" */
96 u16 xmode_first; /* Unprobed modes to try to call anyway */
97 u16 xmode_n; /* Size of unprobed mode range */
98};
99
100#define __videocard struct card_info __attribute__((section(".videocards")))
101extern struct card_info video_cards[], video_cards_end[];
102
103int mode_defined(u16 mode); /* video.c */
104
105/* Basic video information */
106#define ADAPTER_CGA 0 /* CGA/MDA/HGC */
107#define ADAPTER_EGA 1
108#define ADAPTER_VGA 2
109
110extern int adapter;
111extern u16 video_segment;
112extern int force_x, force_y; /* Don't query the BIOS for cols/rows */
113extern int do_restore; /* Restore screen contents */
114extern int graphic_mode; /* Graphics mode with linear frame buffer */
115
116/*
117 * int $0x10 is notorious for touching registers it shouldn't.
118 * gcc doesn't like %ebp being clobbered, so define it as a push/pop
119 * sequence here.
120 */
121#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
122
123/* Accessing VGA indexed registers */
124static inline u8 in_idx(u16 port, u8 index)
125{
126 outb(index, port);
127 return inb(port+1);
128}
129
130static inline void out_idx(u8 v, u16 port, u8 index)
131{
132 outw(index+(v << 8), port);
133}
134
135/* Writes a value to an indexed port and then reads the port again */
136static inline u8 tst_idx(u8 v, u16 port, u8 index)
137{
138 out_idx(port, index, v);
139 return in_idx(port, index);
140}
141
142/* Get the I/O port of the VGA CRTC */
143u16 vga_crtc(void); /* video-vga.c */
144
145#endif /* BOOT_VIDEO_H */
diff --git a/arch/i386/boot/voyager.c b/arch/i386/boot/voyager.c
new file mode 100644
index 000000000000..9221614d0db8
--- /dev/null
+++ b/arch/i386/boot/voyager.c
@@ -0,0 +1,46 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/voyager.c
13 *
14 * Get the Voyager config information
15 */
16
17#include "boot.h"
18
19#ifdef CONFIG_X86_VOYAGER
20
21int query_voyager(void)
22{
23 u8 err;
24 u16 es, di;
25 /* Abuse the apm_bios_info area for this */
26 u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
27
28 data_ptr[0] = 0xff; /* Flag on config not found(?) */
29
30 asm("pushw %%es ; "
31 "int $0x15 ; "
32 "setc %0 ; "
33 "movw %%es, %1 ; "
34 "popw %%es"
35 : "=qm" (err), "=rm" (es), "=D" (di)
36 : "a" (0xffc0));
37
38 if (err)
39 return -1; /* Not Voyager */
40
41 set_fs(es);
42 copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */
43 return 0;
44}
45
46#endif /* CONFIG_X86_VOYAGER */
diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile
index 74f27a463db0..0b6a8551e9e2 100644
--- a/arch/i386/kernel/cpu/Makefile
+++ b/arch/i386/kernel/cpu/Makefile
@@ -8,7 +8,7 @@ obj-y += amd.o
8obj-y += cyrix.o 8obj-y += cyrix.o
9obj-y += centaur.o 9obj-y += centaur.o
10obj-y += transmeta.o 10obj-y += transmeta.o
11obj-y += intel.o intel_cacheinfo.o 11obj-y += intel.o intel_cacheinfo.o addon_cpuid_features.o
12obj-y += rise.o 12obj-y += rise.o
13obj-y += nexgen.o 13obj-y += nexgen.o
14obj-y += umc.o 14obj-y += umc.o
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/i386/kernel/cpu/addon_cpuid_features.c
new file mode 100644
index 000000000000..3e91d3ee26ec
--- /dev/null
+++ b/arch/i386/kernel/cpu/addon_cpuid_features.c
@@ -0,0 +1,50 @@
1
2/*
3 * Routines to indentify additional cpu features that are scattered in
4 * cpuid space.
5 */
6
7#include <linux/cpu.h>
8
9#include <asm/processor.h>
10
11struct cpuid_bit {
12 u16 feature;
13 u8 reg;
14 u8 bit;
15 u32 level;
16};
17
18enum cpuid_regs {
19 CR_EAX = 0,
20 CR_ECX,
21 CR_EDX,
22 CR_EBX
23};
24
25void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
26{
27 u32 max_level;
28 u32 regs[4];
29 const struct cpuid_bit *cb;
30
31 static const struct cpuid_bit cpuid_bits[] = {
32 { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
33 { 0, 0, 0, 0 }
34 };
35
36 for (cb = cpuid_bits; cb->feature; cb++) {
37
38 /* Verify that the level is valid */
39 max_level = cpuid_eax(cb->level & 0xffff0000);
40 if (max_level < cb->level ||
41 max_level > (cb->level | 0xffff))
42 continue;
43
44 cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
45 &regs[CR_ECX], &regs[CR_EDX]);
46
47 if (regs[cb->reg] & (1 << cb->bit))
48 set_bit(cb->feature, c->x86_capability);
49 }
50}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 794d593c47eb..e5419a9dec88 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
353 if ( xlvl >= 0x80000004 ) 353 if ( xlvl >= 0x80000004 )
354 get_model_name(c); /* Default name */ 354 get_model_name(c); /* Default name */
355 } 355 }
356
357 init_scattered_cpuid_features(c);
356 } 358 }
357 359
358 early_intel_workaround(c); 360 early_intel_workaround(c);
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 89d91e6cc972..1e31b6caffb1 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
30 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, 30 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
31 NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, 31 NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
32 NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow", 32 NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
33 "3dnowext", "3dnow",
33 34
34 /* Transmeta-defined */ 35 /* Transmeta-defined */
35 "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, 36 "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
40 /* Other (Linux-defined) */ 41 /* Other (Linux-defined) */
41 "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", 42 "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
42 NULL, NULL, NULL, NULL, 43 NULL, NULL, NULL, NULL,
43 "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL, 44 "constant_tsc", "up", NULL, "arch_perfmon",
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 45 "pebs", "bts", NULL, "sync_rdtsc",
46 "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
45 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
46 48
47 /* Intel-defined (#2) */ 49 /* Intel-defined (#2) */
@@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
57 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 59 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
58 60
59 /* AMD-defined (#2) */ 61 /* AMD-defined (#2) */
60 "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm", 62 "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
61 "sse4a", "misalignsse", 63 "altmovcr8", "abm", "sse4a",
62 "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL, 64 "misalignsse", "3dnowprefetch",
65 "osvw", "ibs", NULL, NULL, NULL, NULL,
66 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
67 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
68
69 /* Auxiliary (Linux-defined) */
70 "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
71 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
63 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 72 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
64 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 73 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
65 }; 74 };
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index 9645bb51f76a..fc822a46897a 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -734,7 +734,7 @@ void __init print_memory_map(char *who)
734 case E820_NVS: 734 case E820_NVS:
735 printk("(ACPI NVS)\n"); 735 printk("(ACPI NVS)\n");
736 break; 736 break;
737 default: printk("type %lu\n", e820.map[i].type); 737 default: printk("type %u\n", e820.map[i].type);
738 break; 738 break;
739 } 739 }
740 } 740 }
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 698c24fe482e..2d61e65eeb50 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
102/* 102/*
103 * Setup options 103 * Setup options
104 */ 104 */
105struct drive_info_struct { char dummy[32]; } drive_info;
106#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
107 defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
108EXPORT_SYMBOL(drive_info);
109#endif
110struct screen_info screen_info; 105struct screen_info screen_info;
111EXPORT_SYMBOL(screen_info); 106EXPORT_SYMBOL(screen_info);
112struct apm_info apm_info; 107struct apm_info apm_info;
113EXPORT_SYMBOL(apm_info); 108EXPORT_SYMBOL(apm_info);
114struct sys_desc_table_struct {
115 unsigned short length;
116 unsigned char table[0];
117};
118struct edid_info edid_info; 109struct edid_info edid_info;
119EXPORT_SYMBOL_GPL(edid_info); 110EXPORT_SYMBOL_GPL(edid_info);
120struct ist_info ist_info; 111struct ist_info ist_info;
@@ -134,7 +125,7 @@ unsigned long saved_videomode;
134 125
135static char __initdata command_line[COMMAND_LINE_SIZE]; 126static char __initdata command_line[COMMAND_LINE_SIZE];
136 127
137unsigned char __initdata boot_params[PARAM_SIZE]; 128struct boot_params __initdata boot_params;
138 129
139#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 130#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
140struct edd edd; 131struct edd edd;
@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
528#endif 519#endif
529 520
530 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); 521 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
531 drive_info = DRIVE_INFO;
532 screen_info = SCREEN_INFO; 522 screen_info = SCREEN_INFO;
533 edid_info = EDID_INFO; 523 edid_info = EDID_INFO;
534 apm_info.bios = APM_BIOS_INFO; 524 apm_info.bios = APM_BIOS_INFO;
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
deleted file mode 100644
index f1d1eacf4ab0..000000000000
--- a/arch/i386/kernel/verify_cpu.S
+++ /dev/null
@@ -1,94 +0,0 @@
1/* Check if CPU has some minimum CPUID bits
2 This runs in 16bit mode so that the caller can still use the BIOS
3 to output errors on the screen */
4#include <asm/cpufeature.h>
5#include <asm/msr.h>
6
7verify_cpu:
8 pushfl # Save caller passed flags
9 pushl $0 # Kill any dangerous flags
10 popfl
11
12#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
13 pushfl
14 pop %eax
15 orl $(1<<18),%eax # try setting AC
16 push %eax
17 popfl
18 pushfl
19 popl %eax
20 testl $(1<<18),%eax
21 jz bad
22#endif
23#if REQUIRED_MASK1 != 0
24 pushfl # standard way to check for cpuid
25 popl %eax
26 movl %eax,%ebx
27 xorl $0x200000,%eax
28 pushl %eax
29 popfl
30 pushfl
31 popl %eax
32 cmpl %eax,%ebx
33 pushfl # standard way to check for cpuid
34 popl %eax
35 movl %eax,%ebx
36 xorl $0x200000,%eax
37 pushl %eax
38 popfl
39 pushfl
40 popl %eax
41 cmpl %eax,%ebx
42 jz bad # REQUIRED_MASK1 != 0 requires CPUID
43
44 movl $0x0,%eax # See if cpuid 1 is implemented
45 cpuid
46 cmpl $0x1,%eax
47 jb bad # no cpuid 1
48
49#if REQUIRED_MASK1 & NEED_CMPXCHG64
50 /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
51 cmpl $0x746e6543,%ebx # Cent
52 jne 1f
53 cmpl $0x48727561,%edx # aurH
54 jne 1f
55 cmpl $0x736c7561,%ecx # auls
56 jne 1f
57 movl $1,%eax # check model
58 cpuid
59 movl %eax,%ebx
60 shr $8,%ebx
61 andl $0xf,%ebx
62 cmp $6,%ebx # check family == 6
63 jne 1f
64 shr $4,%eax
65 andl $0xf,%eax
66 cmpl $6,%eax # check model >= 6
67 jb 1f
68 # assume models >= 6 all support this MSR
69 movl $MSR_VIA_FCR,%ecx
70 rdmsr
71 orl $((1<<1)|(1<<7)),%eax # enable CMPXCHG64 and PGE
72 wrmsr
731:
74#endif
75 movl $0x1,%eax # Does the cpu have what it takes
76 cpuid
77
78#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
79#error add proper model checking here
80#endif
81
82 andl $REQUIRED_MASK1,%edx
83 xorl $REQUIRED_MASK1,%edx
84 jnz bad
85#endif /* REQUIRED_MASK1 */
86
87 popfl
88 xor %eax,%eax
89 ret
90
91bad:
92 popfl
93 movl $1,%eax
94 ret
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a00fabe2e4e0..5c863bcd5614 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -117,9 +117,9 @@ config MACH_JAZZ
117 select ARC32 117 select ARC32
118 select ARCH_MAY_HAVE_PC_FDC 118 select ARCH_MAY_HAVE_PC_FDC
119 select GENERIC_ISA_DMA 119 select GENERIC_ISA_DMA
120 select I8253
121 select I8259 120 select I8259
122 select ISA 121 select ISA
122 select PCSPEAKER
123 select SYS_HAS_CPU_R4X00 123 select SYS_HAS_CPU_R4X00
124 select SYS_SUPPORTS_32BIT_KERNEL 124 select SYS_SUPPORTS_32BIT_KERNEL
125 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL 125 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -347,9 +347,9 @@ config QEMU
347 select DMA_COHERENT 347 select DMA_COHERENT
348 select GENERIC_ISA_DMA 348 select GENERIC_ISA_DMA
349 select HAVE_STD_PC_SERIAL_PORT 349 select HAVE_STD_PC_SERIAL_PORT
350 select I8253
351 select I8259 350 select I8259
352 select ISA 351 select ISA
352 select PCSPEAKER
353 select SWAP_IO_SPACE 353 select SWAP_IO_SPACE
354 select SYS_HAS_CPU_MIPS32_R1 354 select SYS_HAS_CPU_MIPS32_R1
355 select SYS_SUPPORTS_32BIT_KERNEL 355 select SYS_SUPPORTS_32BIT_KERNEL
@@ -562,9 +562,9 @@ config SNI_RM
562 select HW_HAS_EISA 562 select HW_HAS_EISA
563 select HW_HAS_PCI 563 select HW_HAS_PCI
564 select IRQ_CPU 564 select IRQ_CPU
565 select I8253
566 select I8259 565 select I8259
567 select ISA 566 select ISA
567 select PCSPEAKER
568 select SWAP_IO_SPACE if CPU_BIG_ENDIAN 568 select SWAP_IO_SPACE if CPU_BIG_ENDIAN
569 select SYS_HAS_CPU_R4X00 569 select SYS_HAS_CPU_R4X00
570 select SYS_HAS_CPU_R5000 570 select SYS_HAS_CPU_R5000
@@ -1404,6 +1404,19 @@ config MIPS_MT_SMTC_INSTANT_REPLAY
1404 it off), but ensures that IPIs are handled promptly even under 1404 it off), but ensures that IPIs are handled promptly even under
1405 heavy I/O interrupt load. 1405 heavy I/O interrupt load.
1406 1406
1407config MIPS_MT_SMTC_IM_BACKSTOP
1408 bool "Use per-TC register bits as backstop for inhibited IM bits"
1409 depends on MIPS_MT_SMTC
1410 default y
1411 help
1412 To support multiple TC microthreads acting as "CPUs" within
1413 a VPE, VPE-wide interrupt mask bits must be specially manipulated
1414 during interrupt handling. To support legacy drivers and interrupt
1415 controller management code, SMTC has a "backstop" to track and
1416 if necessary restore the interrupt mask. This has some performance
1417 impact on interrupt service overhead. Disable it only if you know
1418 what you are doing.
1419
1407config MIPS_VPE_LOADER_TOM 1420config MIPS_VPE_LOADER_TOM
1408 bool "Load VPE program into memory hidden from linux" 1421 bool "Load VPE program into memory hidden from linux"
1409 depends on MIPS_VPE_LOADER 1422 depends on MIPS_VPE_LOADER
@@ -1851,7 +1864,7 @@ config MMU
1851 bool 1864 bool
1852 default y 1865 default y
1853 1866
1854config I8253 1867config PCSPEAKER
1855 bool 1868 bool
1856 1869
1857source "drivers/pcmcia/Kconfig" 1870source "drivers/pcmcia/Kconfig"
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 13fe187f35d6..fdf2b85a69c8 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -100,9 +100,6 @@ void __init plat_mem_setup(void)
100 argptr = prom_getcmdline(); 100 argptr = prom_getcmdline();
101 /* default panel */ 101 /* default panel */
102 /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ 102 /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
103#ifdef CONFIG_MIPS_HYDROGEN3
104 strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
105#endif
106 } 103 }
107#endif 104#endif
108 105
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index dd04eece9fd3..8a0b4ac5283d 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -241,7 +241,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
241# 241#
242CONFIG_ISA=y 242CONFIG_ISA=y
243CONFIG_MMU=y 243CONFIG_MMU=y
244CONFIG_I8253=y 244CONFIG_PCSPEAKER=y
245 245
246# 246#
247# PCCARD (PCMCIA/CardBus) support 247# PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index 6cca105832ca..703de002e372 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -221,7 +221,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
221# 221#
222CONFIG_ISA=y 222CONFIG_ISA=y
223CONFIG_MMU=y 223CONFIG_MMU=y
224CONFIG_I8253=y 224CONFIG_PCSPEAKER=y
225 225
226# 226#
227# PCCARD (PCMCIA/CardBus) support 227# PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 1a67a85aabbb..a5dc5cb97aae 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -251,7 +251,7 @@ CONFIG_PCI=y
251CONFIG_ISA=y 251CONFIG_ISA=y
252# CONFIG_EISA is not set 252# CONFIG_EISA is not set
253CONFIG_MMU=y 253CONFIG_MMU=y
254CONFIG_I8253=y 254CONFIG_PCSPEAKER=y
255 255
256# 256#
257# PCCARD (PCMCIA/CardBus) support 257# PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index f1cdb12f7925..f342d8c887b8 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -592,8 +592,6 @@ CONFIG_LEGACY_PTY_COUNT=256
592# CONFIG_WATCHDOG is not set 592# CONFIG_WATCHDOG is not set
593# CONFIG_HW_RANDOM is not set 593# CONFIG_HW_RANDOM is not set
594# CONFIG_RTC is not set 594# CONFIG_RTC is not set
595CONFIG_GEN_RTC=y
596CONFIG_GEN_RTC_X=y
597# CONFIG_DTLK is not set 595# CONFIG_DTLK is not set
598# CONFIG_R3964 is not set 596# CONFIG_R3964 is not set
599# CONFIG_APPLICOM is not set 597# CONFIG_APPLICOM is not set
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 961594cb5214..5c8085b6d7ab 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -63,7 +63,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
63 63
64obj-$(CONFIG_64BIT) += cpu-bugs64.o 64obj-$(CONFIG_64BIT) += cpu-bugs64.o
65 65
66obj-$(CONFIG_I8253) += i8253.o 66obj-$(CONFIG_PCSPEAKER) += pcspeaker.o
67 67
68obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 68obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
69obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 69obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 686249c5c328..e29598ae939d 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -84,6 +84,7 @@ FEXPORT(restore_all) # restore full frame
84 LONG_S sp, TI_REGS($28) 84 LONG_S sp, TI_REGS($28)
85 jal deferred_smtc_ipi 85 jal deferred_smtc_ipi
86 LONG_S s0, TI_REGS($28) 86 LONG_S s0, TI_REGS($28)
87#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
87/* Re-arm any temporarily masked interrupts not explicitly "acked" */ 88/* Re-arm any temporarily masked interrupts not explicitly "acked" */
88 mfc0 v0, CP0_TCSTATUS 89 mfc0 v0, CP0_TCSTATUS
89 ori v1, v0, TCSTATUS_IXMT 90 ori v1, v0, TCSTATUS_IXMT
@@ -110,6 +111,7 @@ FEXPORT(restore_all) # restore full frame
110 _ehb 111 _ehb
111 xor t0, t0, t3 112 xor t0, t0, t3
112 mtc0 t0, CP0_TCCONTEXT 113 mtc0 t0, CP0_TCCONTEXT
114#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
113#endif /* CONFIG_MIPS_MT_SMTC */ 115#endif /* CONFIG_MIPS_MT_SMTC */
114 .set noat 116 .set noat
115 RESTORE_TEMP 117 RESTORE_TEMP
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 297bd56c2347..c0f19d638b98 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -243,9 +243,11 @@ NESTED(except_vec_vi_handler, 0, sp)
243 */ 243 */
244 mfc0 t1, CP0_STATUS 244 mfc0 t1, CP0_STATUS
245 and t0, a0, t1 245 and t0, a0, t1
246#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
246 mfc0 t2, CP0_TCCONTEXT 247 mfc0 t2, CP0_TCCONTEXT
247 or t0, t0, t2 248 or t0, t0, t2
248 mtc0 t0, CP0_TCCONTEXT 249 mtc0 t0, CP0_TCCONTEXT
250#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
249 xor t1, t1, t0 251 xor t1, t1, t0
250 mtc0 t1, CP0_STATUS 252 mtc0 t1, CP0_STATUS
251 _ehb 253 _ehb
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/pcspeaker.c
index 475df6904219..475df6904219 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/pcspeaker.c
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 06729596812f..d9bfae53c43f 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -85,12 +85,7 @@
85 move $28, a2 85 move $28, a2
86 cpu_restore_nonscratch a1 86 cpu_restore_nonscratch a1
87 87
88#if (_THREAD_SIZE - 32) < 0x10000 88 PTR_ADDU t0, $28, _THREAD_SIZE - 32
89 PTR_ADDIU t0, $28, _THREAD_SIZE - 32
90#else
91 PTR_LI t0, _THREAD_SIZE - 32
92 PTR_ADDU t0, $28
93#endif
94 set_saved_sp t0, t1, t2 89 set_saved_sp t0, t1, t2
95#ifdef CONFIG_MIPS_MT_SMTC 90#ifdef CONFIG_MIPS_MT_SMTC
96 /* Read-modify-writes of Status must be atomic on a VPE */ 91 /* Read-modify-writes of Status must be atomic on a VPE */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 80ea4fa95bd9..5e9fa83c4ef0 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -373,7 +373,7 @@ asmlinkage void do_be(struct pt_regs *regs)
373 action = MIPS_BE_FIXUP; 373 action = MIPS_BE_FIXUP;
374 374
375 if (board_be_handler) 375 if (board_be_handler)
376 action = board_be_handler(regs, fixup != 0); 376 action = board_be_handler(regs, fixup != NULL);
377 377
378 switch (action) { 378 switch (action) {
379 case MIPS_BE_DISCARD: 379 case MIPS_BE_DISCARD:
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 1a4db7dc77cb..465ff0ec85b9 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -10,6 +10,7 @@
10#include <asm/mipsregs.h> 10#include <asm/mipsregs.h>
11#include <asm/page.h> 11#include <asm/page.h>
12#include <asm/pgtable.h> 12#include <asm/pgtable.h>
13#include <asm/tlbdebug.h>
13 14
14static inline const char *msk2str(unsigned int mask) 15static inline const char *msk2str(unsigned int mask)
15{ 16{
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 52f87795ecc3..9cee907975ae 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -11,6 +11,7 @@
11#include <asm/mipsregs.h> 11#include <asm/mipsregs.h>
12#include <asm/page.h> 12#include <asm/page.h>
13#include <asm/pgtable.h> 13#include <asm/pgtable.h>
14#include <asm/tlbdebug.h>
14 15
15extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */ 16extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
16 17
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 2388f7f3ffde..58d14f4d9349 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -12,6 +12,7 @@
12 12
13#include <asm/addrspace.h> 13#include <asm/addrspace.h>
14#include <asm/bug.h> 14#include <asm/bug.h>
15#include <asm/cacheflush.h>
15 16
16#ifndef CKSEG2 17#ifndef CKSEG2
17#define CKSEG2 CKSSEG 18#define CKSEG2 CKSSEG
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
index d86b37235cf6..5cbc3509ab52 100644
--- a/arch/mips/mipssim/sim_int.c
+++ b/arch/mips/mipssim/sim_int.c
@@ -77,7 +77,7 @@ asmlinkage void plat_irq_dispatch(void)
77 irq = irq_ffs(pending); 77 irq = irq_ffs(pending);
78 78
79 if (irq > 0) 79 if (irq > 0)
80 do_IRQ(MIPSCPU_INT_BASE + irq); 80 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
81 else 81 else
82 spurious_interrupt(); 82 spurious_interrupt();
83} 83}
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index 3643582bdade..60e66906be65 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -84,7 +84,7 @@ static void __init serial_init(void)
84 /* hardware int 4 - the serial int, is CPU int 6 84 /* hardware int 4 - the serial int, is CPU int 6
85 but poll for now */ 85 but poll for now */
86 s.irq = 0; 86 s.irq = 0;
87 s.uartclk = BASE_BAUD * 16; 87 s.uartclk = 1843200;
88 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; 88 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
89 s.iotype = UPIO_PORT; 89 s.iotype = UPIO_PORT;
90 s.regshift = 0; 90 s.regshift = 0;
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
index 874a18e8ac24..a0f5a5dca1b2 100644
--- a/arch/mips/mipssim/sim_time.c
+++ b/arch/mips/mipssim/sim_time.c
@@ -5,7 +5,6 @@
5#include <linux/spinlock.h> 5#include <linux/spinlock.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/mc146818rtc.h> 7#include <linux/mc146818rtc.h>
8#include <linux/mipsregs.h>
9#include <linux/smp.h> 8#include <linux/smp.h>
10#include <linux/timex.h> 9#include <linux/timex.h>
11 10
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 8108231f2e20..99d8f4fd3ff4 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -269,7 +269,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
269 } 269 }
270 270
271 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { 271 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
272 struct pci_dev *dev = pci_dev_b(ln); 272 dev = pci_dev_b(ln);
273 273
274 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) 274 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
275 pcibios_fixup_device_resources(dev, bus); 275 pcibios_fixup_device_resources(dev, bus);
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
deleted file mode 100644
index 97c73c793c35..000000000000
--- a/arch/mips/sibyte/swarm/time.c
+++ /dev/null
@@ -1,244 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19/*
20 * Time routines for the swarm board. We pass all the hard stuff
21 * through to the sb1250 handling code. Only thing we really keep
22 * track of here is what time of day we think it is. And we don't
23 * really even do a good job of that...
24 */
25
26
27#include <linux/bcd.h>
28#include <linux/init.h>
29#include <linux/time.h>
30#include <linux/sched.h>
31#include <linux/spinlock.h>
32#include <asm/system.h>
33#include <asm/addrspace.h>
34#include <asm/io.h>
35
36#include <asm/sibyte/sb1250.h>
37#include <asm/sibyte/sb1250_regs.h>
38#include <asm/sibyte/sb1250_smbus.h>
39
40static unsigned long long sec_bias = 0;
41static unsigned int usec_bias = 0;
42
43/* Xicor 1241 definitions */
44
45/*
46 * Register bits
47 */
48
49#define X1241REG_SR_BAT 0x80 /* currently on battery power */
50#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */
51#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */
52#define X1241REG_SR_RTCF 0x01 /* clock failed */
53#define X1241REG_BL_BP2 0x80 /* block protect 2 */
54#define X1241REG_BL_BP1 0x40 /* block protect 1 */
55#define X1241REG_BL_BP0 0x20 /* block protect 0 */
56#define X1241REG_BL_WD1 0x10
57#define X1241REG_BL_WD0 0x08
58#define X1241REG_HR_MIL 0x80 /* military time format */
59
60/*
61 * Register numbers
62 */
63
64#define X1241REG_BL 0x10 /* block protect bits */
65#define X1241REG_INT 0x11 /* */
66#define X1241REG_SC 0x30 /* Seconds */
67#define X1241REG_MN 0x31 /* Minutes */
68#define X1241REG_HR 0x32 /* Hours */
69#define X1241REG_DT 0x33 /* Day of month */
70#define X1241REG_MO 0x34 /* Month */
71#define X1241REG_YR 0x35 /* Year */
72#define X1241REG_DW 0x36 /* Day of Week */
73#define X1241REG_Y2K 0x37 /* Year 2K */
74#define X1241REG_SR 0x3F /* Status register */
75
76#define X1241_CCR_ADDRESS 0x6F
77
78#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
79
80static int xicor_read(uint8_t addr)
81{
82 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
83 ;
84
85 __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
86 __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
87 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
88 SMB_CSR(R_SMB_START));
89
90 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
91 ;
92
93 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
94 SMB_CSR(R_SMB_START));
95
96 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
97 ;
98
99 if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
100 /* Clear error bit by writing a 1 */
101 __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
102 return -1;
103 }
104
105 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
106}
107
108static int xicor_write(uint8_t addr, int b)
109{
110 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
111 ;
112
113 __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
114 __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
115 __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
116 SMB_CSR(R_SMB_START));
117
118 while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
119 ;
120
121 if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
122 /* Clear error bit by writing a 1 */
123 __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
124 return -1;
125 } else {
126 return 0;
127 }
128}
129
130/*
131 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
132 * called 500 ms after the second nowtime has started, because when
133 * nowtime is written into the registers of the CMOS clock, it will
134 * jump to the next second precisely 500 ms later. Check the Motorola
135 * MC146818A or Dallas DS12887 data sheet for details.
136 *
137 * BUG: This routine does not handle hour overflow properly; it just
138 * sets the minutes. Usually you'll only notice that after reboot!
139 */
140int set_rtc_mmss(unsigned long nowtime)
141{
142 int retval = 0;
143 int real_seconds, real_minutes, cmos_minutes;
144
145 cmos_minutes = xicor_read(X1241REG_MN);
146 cmos_minutes = BCD2BIN(cmos_minutes);
147
148 /*
149 * since we're only adjusting minutes and seconds,
150 * don't interfere with hour overflow. This avoids
151 * messing with unknown time zones but requires your
152 * RTC not to be off by more than 15 minutes
153 */
154 real_seconds = nowtime % 60;
155 real_minutes = nowtime / 60;
156 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
157 real_minutes += 30; /* correct for half hour time zone */
158 real_minutes %= 60;
159
160 /* unlock writes to the CCR */
161 xicor_write(X1241REG_SR, X1241REG_SR_WEL);
162 xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
163
164 if (abs(real_minutes - cmos_minutes) < 30) {
165 real_seconds = BIN2BCD(real_seconds);
166 real_minutes = BIN2BCD(real_minutes);
167 xicor_write(X1241REG_SC, real_seconds);
168 xicor_write(X1241REG_MN, real_minutes);
169 } else {
170 printk(KERN_WARNING
171 "set_rtc_mmss: can't update from %d to %d\n",
172 cmos_minutes, real_minutes);
173 retval = -1;
174 }
175
176 xicor_write(X1241REG_SR, 0);
177
178 printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
179
180 return retval;
181}
182
183static unsigned long __init get_swarm_time(void)
184{
185 unsigned int year, mon, day, hour, min, sec, y2k;
186
187 sec = xicor_read(X1241REG_SC);
188 min = xicor_read(X1241REG_MN);
189 hour = xicor_read(X1241REG_HR);
190
191 if (hour & X1241REG_HR_MIL) {
192 hour &= 0x3f;
193 } else {
194 if (hour & 0x20)
195 hour = (hour & 0xf) + 0x12;
196 }
197
198 sec = BCD2BIN(sec);
199 min = BCD2BIN(min);
200 hour = BCD2BIN(hour);
201
202 day = xicor_read(X1241REG_DT);
203 mon = xicor_read(X1241REG_MO);
204 year = xicor_read(X1241REG_YR);
205 y2k = xicor_read(X1241REG_Y2K);
206
207 day = BCD2BIN(day);
208 mon = BCD2BIN(mon);
209 year = BCD2BIN(year);
210 y2k = BCD2BIN(y2k);
211
212 year += (y2k * 100);
213
214 return mktime(year, mon, day, hour, min, sec);
215}
216
217/*
218 * Bring up the timer at 100 Hz.
219 */
220void __init swarm_time_init(void)
221{
222 unsigned int flags;
223 int status;
224
225 /* Set up the scd general purpose timer 0 to cpu 0 */
226 sb1250_time_init();
227
228 /* Establish communication with the Xicor 1241 RTC */
229 /* XXXKW how do I share the SMBus with the I2C subsystem? */
230
231 __raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
232 __raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
233
234 if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
235 printk("x1241: couldn't detect on SWARM SMBus 1\n");
236 } else {
237 if (status & X1241REG_SR_RTCF)
238 printk("x1241: battery failed -- time is probably wrong\n");
239 write_seqlock_irqsave(&xtime_lock, flags);
240 xtime.tv_sec = get_swarm_time();
241 xtime.tv_nsec = 0;
242 write_sequnlock_irqrestore(&xtime_lock, flags);
243 }
244}
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index 6850a29defcd..acc9ba76c1a9 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -87,8 +87,8 @@ static struct platform_device snirm_82596_pdev = {
87 87
88static struct resource snirm_53c710_rsrc[] = { 88static struct resource snirm_53c710_rsrc[] = {
89 { 89 {
90 .start = 0xb9000000, 90 .start = 0x19000000,
91 .end = 0xb90fffff, 91 .end = 0x190fffff,
92 .flags = IORESOURCE_MEM 92 .flags = IORESOURCE_MEM
93 }, 93 },
94 { 94 {
@@ -106,8 +106,8 @@ static struct platform_device snirm_53c710_pdev = {
106 106
107static struct resource sc26xx_rsrc[] = { 107static struct resource sc26xx_rsrc[] = {
108 { 108 {
109 .start = 0xbc070000, 109 .start = 0x1c070000,
110 .end = 0xbc0700ff, 110 .end = 0x1c0700ff,
111 .flags = IORESOURCE_MEM 111 .flags = IORESOURCE_MEM
112 }, 112 },
113 { 113 {
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 4bfda020fdc7..28a11d8605ce 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -88,8 +88,8 @@ static struct platform_device snirm_82596_rm200_pdev = {
88 88
89static struct resource snirm_53c710_rm200_rsrc[] = { 89static struct resource snirm_53c710_rm200_rsrc[] = {
90 { 90 {
91 .start = 0xb9000000, 91 .start = 0x19000000,
92 .end = 0xb90fffff, 92 .end = 0x190fffff,
93 .flags = IORESOURCE_MEM 93 .flags = IORESOURCE_MEM
94 }, 94 },
95 { 95 {
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
index f842783acd86..d0d84ec8d63d 100644
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -2,4 +2,4 @@
2# Makefile for common code of the NEC VR4100 series. 2# Makefile for common code of the NEC VR4100 series.
3# 3#
4 4
5obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o 5obj-y += bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
new file mode 100644
index 000000000000..d21f6f2d22a3
--- /dev/null
+++ b/arch/mips/vr41xx/common/giu.c
@@ -0,0 +1,122 @@
1/*
2 * NEC VR4100 series GIU platform device.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/platform_device.h>
24
25#include <asm/cpu.h>
26#include <asm/vr41xx/giu.h>
27#include <asm/vr41xx/irq.h>
28
29static struct resource giu_50pins_pullupdown_resource[] __initdata = {
30 {
31 .start = 0x0b000100,
32 .end = 0x0b00011f,
33 .flags = IORESOURCE_MEM,
34 },
35 {
36 .start = 0x0b0002e0,
37 .end = 0x0b0002e3,
38 .flags = IORESOURCE_MEM,
39 },
40 {
41 .start = GIUINT_IRQ,
42 .end = GIUINT_IRQ,
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static struct resource giu_36pins_resource[] __initdata = {
48 {
49 .start = 0x0f000140,
50 .end = 0x0f00015f,
51 .flags = IORESOURCE_MEM,
52 },
53 {
54 .start = GIUINT_IRQ,
55 .end = GIUINT_IRQ,
56 .flags = IORESOURCE_IRQ,
57 },
58};
59
60static struct resource giu_48pins_resource[] __initdata = {
61 {
62 .start = 0x0f000140,
63 .end = 0x0f000167,
64 .flags = IORESOURCE_MEM,
65 },
66 {
67 .start = GIUINT_IRQ,
68 .end = GIUINT_IRQ,
69 .flags = IORESOURCE_IRQ,
70 },
71};
72
73static int __init vr41xx_giu_add(void)
74{
75 struct platform_device *pdev;
76 struct resource *res;
77 unsigned int num;
78 int retval;
79
80 pdev = platform_device_alloc("GIU", -1);
81 if (!pdev)
82 return -ENOMEM;
83
84 switch (current_cpu_data.cputype) {
85 case CPU_VR4111:
86 case CPU_VR4121:
87 pdev->id = GPIO_50PINS_PULLUPDOWN;
88 res = giu_50pins_pullupdown_resource;
89 num = ARRAY_SIZE(giu_50pins_pullupdown_resource);
90 break;
91 case CPU_VR4122:
92 case CPU_VR4131:
93 pdev->id = GPIO_36PINS;
94 res = giu_36pins_resource;
95 num = ARRAY_SIZE(giu_36pins_resource);
96 break;
97 case CPU_VR4133:
98 pdev->id = GPIO_48PINS_EDGE_SELECT;
99 res = giu_48pins_resource;
100 num = ARRAY_SIZE(giu_48pins_resource);
101 break;
102 default:
103 retval = -ENODEV;
104 goto err_free_device;
105 }
106
107 retval = platform_device_add_resources(pdev, res, num);
108 if (retval)
109 goto err_free_device;
110
111 retval = platform_device_add(pdev);
112 if (retval)
113 goto err_free_device;
114
115 return 0;
116
117err_free_device:
118 platform_device_put(pdev);
119
120 return retval;
121}
122device_initcall(vr41xx_giu_add);
diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c
new file mode 100644
index 000000000000..cce605b3d688
--- /dev/null
+++ b/arch/mips/vr41xx/common/rtc.c
@@ -0,0 +1,117 @@
1/*
2 * NEC VR4100 series RTC platform device.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/platform_device.h>
24
25#include <asm/cpu.h>
26#include <asm/vr41xx/irq.h>
27
28static struct resource rtc_type1_resource[] __initdata = {
29 {
30 .start = 0x0b0000c0,
31 .end = 0x0b0000df,
32 .flags = IORESOURCE_MEM,
33 },
34 {
35 .start = 0x0b0001c0,
36 .end = 0x0b0001df,
37 .flags = IORESOURCE_MEM,
38 },
39 {
40 .start = ELAPSEDTIME_IRQ,
41 .end = ELAPSEDTIME_IRQ,
42 .flags = IORESOURCE_IRQ,
43 },
44 {
45 .start = RTCLONG1_IRQ,
46 .end = RTCLONG1_IRQ,
47 .flags = IORESOURCE_IRQ,
48 },
49};
50
51static struct resource rtc_type2_resource[] __initdata = {
52 {
53 .start = 0x0f000100,
54 .end = 0x0f00011f,
55 .flags = IORESOURCE_MEM,
56 },
57 {
58 .start = 0x0f000120,
59 .end = 0x0f00013f,
60 .flags = IORESOURCE_MEM,
61 },
62 {
63 .start = ELAPSEDTIME_IRQ,
64 .end = ELAPSEDTIME_IRQ,
65 .flags = IORESOURCE_IRQ,
66 },
67 {
68 .start = RTCLONG1_IRQ,
69 .end = RTCLONG1_IRQ,
70 .flags = IORESOURCE_IRQ,
71 },
72};
73
74static int __init vr41xx_rtc_add(void)
75{
76 struct platform_device *pdev;
77 struct resource *res;
78 unsigned int num;
79 int retval;
80
81 pdev = platform_device_alloc("RTC", -1);
82 if (!pdev)
83 return -ENOMEM;
84
85 switch (current_cpu_data.cputype) {
86 case CPU_VR4111:
87 case CPU_VR4121:
88 res = rtc_type1_resource;
89 num = ARRAY_SIZE(rtc_type1_resource);
90 break;
91 case CPU_VR4122:
92 case CPU_VR4131:
93 case CPU_VR4133:
94 res = rtc_type2_resource;
95 num = ARRAY_SIZE(rtc_type2_resource);
96 break;
97 default:
98 retval = -ENODEV;
99 goto err_free_device;
100 }
101
102 retval = platform_device_add_resources(pdev, res, num);
103 if (retval)
104 goto err_free_device;
105
106 retval = platform_device_add(pdev);
107 if (retval)
108 goto err_free_device;
109
110 return 0;
111
112err_free_device:
113 platform_device_put(pdev);
114
115 return retval;
116}
117device_initcall(vr41xx_rtc_add);
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
new file mode 100644
index 000000000000..a1e774142163
--- /dev/null
+++ b/arch/mips/vr41xx/common/siu.c
@@ -0,0 +1,120 @@
1/*
2 * NEC VR4100 series SIU platform device.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/platform_device.h>
24#include <linux/serial_core.h>
25
26#include <asm/cpu.h>
27#include <asm/vr41xx/siu.h>
28
29static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
30 PORT_VR41XX_SIU,
31 PORT_UNKNOWN,
32};
33
34static struct resource siu_type1_resource[] __initdata = {
35 {
36 .start = 0x0c000000,
37 .end = 0x0c00000a,
38 .flags = IORESOURCE_MEM,
39 },
40 {
41 .start = SIU_IRQ,
42 .end = SIU_IRQ,
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
48 PORT_VR41XX_SIU,
49 PORT_VR41XX_DSIU,
50};
51
52static struct resource siu_type2_resource[] __initdata = {
53 {
54 .start = 0x0f000800,
55 .end = 0x0f00080a,
56 .flags = IORESOURCE_MEM,
57 },
58 {
59 .start = 0x0f000820,
60 .end = 0x0f000829,
61 .flags = IORESOURCE_MEM,
62 },
63 {
64 .start = SIU_IRQ,
65 .end = SIU_IRQ,
66 .flags = IORESOURCE_IRQ,
67 },
68 {
69 .start = DSIU_IRQ,
70 .end = DSIU_IRQ,
71 .flags = IORESOURCE_IRQ,
72 },
73};
74
75static int __init vr41xx_siu_add(void)
76{
77 struct platform_device *pdev;
78 struct resource *res;
79 unsigned int num;
80 int retval;
81
82 pdev = platform_device_alloc("SIU", -1);
83 if (!pdev)
84 return -ENOMEM;
85
86 switch (current_cpu_data.cputype) {
87 case CPU_VR4111:
88 case CPU_VR4121:
89 pdev->dev.platform_data = siu_type1_ports;
90 res = siu_type1_resource;
91 num = ARRAY_SIZE(siu_type1_resource);
92 break;
93 case CPU_VR4122:
94 case CPU_VR4131:
95 case CPU_VR4133:
96 pdev->dev.platform_data = siu_type2_ports;
97 res = siu_type2_resource;
98 num = ARRAY_SIZE(siu_type2_resource);
99 break;
100 default:
101 retval = -ENODEV;
102 goto err_free_device;
103 }
104
105 retval = platform_device_add_resources(pdev, res, num);
106 if (retval)
107 goto err_free_device;
108
109 retval = platform_device_add(pdev);
110 if (retval)
111 goto err_free_device;
112
113 return 0;
114
115err_free_device:
116 platform_device_put(pdev);
117
118 return retval;
119}
120device_initcall(vr41xx_siu_add);
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 5ce94430c019..8bdd25ac1542 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -427,6 +427,10 @@ config NR_CPUS
427 This is purely to save memory - each supported CPU requires 427 This is purely to save memory - each supported CPU requires
428 memory in the static kernel configuration. 428 memory in the static kernel configuration.
429 429
430config PHYSICAL_ALIGN
431 hex
432 default "0x200000"
433
430config HOTPLUG_CPU 434config HOTPLUG_CPU
431 bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)" 435 bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
432 depends on SMP && HOTPLUG && EXPERIMENTAL 436 depends on SMP && HOTPLUG && EXPERIMENTAL
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
index ee6f6505f95f..67096389de1f 100644
--- a/arch/x86_64/boot/Makefile
+++ b/arch/x86_64/boot/Makefile
@@ -1,135 +1,9 @@
1# 1#
2# arch/x86_64/boot/Makefile 2# arch/x86_64/boot/Makefile
3# 3#
4# This file is subject to the terms and conditions of the GNU General Public 4# The actual boot code is shared with i386 including the Makefile.
5# License. See the file "COPYING" in the main directory of this archive 5# So tell kbuild that we fetch the code from i386 and include the
6# for more details. 6# Makefile from i386 too.
7#
8# Copyright (C) 1994 by Linus Torvalds
9#
10
11# ROOT_DEV specifies the default root-device when making the image.
12# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
13# the default of FLOPPY is used by 'build'.
14
15ROOT_DEV := CURRENT
16
17# If you want to preset the SVGA mode, uncomment the next line and
18# set SVGA_MODE to whatever number you want.
19# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
20# The number is the same as you would ordinarily press at bootup.
21
22SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
23
24# If you want the RAM disk device, define this to be the size in blocks.
25
26#RAMDISK := -DRAMDISK=512
27
28targets := vmlinux.bin bootsect bootsect.o \
29 setup setup.o bzImage mtools.conf
30
31EXTRA_CFLAGS := -m32
32
33hostprogs-y := tools/build
34HOST_EXTRACFLAGS += $(LINUXINCLUDE)
35subdir- := compressed/ #Let make clean descend in compressed/
36# ---------------------------------------------------------------------------
37
38$(obj)/bzImage: IMAGE_OFFSET := 0x100000
39$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
40$(obj)/bzImage: BUILDFLAGS := -b
41
42quiet_cmd_image = BUILD $@
43cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
44 $(obj)/vmlinux.bin $(ROOT_DEV) > $@
45
46$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
47 $(obj)/vmlinux.bin $(obj)/tools/build FORCE
48 $(call if_changed,image)
49 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
50
51$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
52 $(call if_changed,objcopy)
53
54LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
55LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext
56
57$(obj)/setup $(obj)/bootsect: %: %.o FORCE
58 $(call if_changed,ld)
59
60$(obj)/compressed/vmlinux: FORCE
61 $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
62
63# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
64FDARGS =
65# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
66FDINITRD =
67
68image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
69
70$(obj)/mtools.conf: $(src)/mtools.conf.in
71 sed -e 's|@OBJ@|$(obj)|g' < $< > $@
72
73# This requires write access to /dev/fd0
74zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
75 MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync
76 syslinux /dev/fd0 ; sync
77 echo '$(image_cmdline)' | \
78 MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
79 if [ -f '$(FDINITRD)' ] ; then \
80 MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
81 fi
82 MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync
83
84# These require being root or having syslinux 2.02 or higher installed
85fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
86 dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
87 MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync
88 syslinux $(obj)/fdimage ; sync
89 echo '$(image_cmdline)' | \
90 MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
91 if [ -f '$(FDINITRD)' ] ; then \
92 MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
93 fi
94 MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync
95
96fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
97 dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
98 MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync
99 syslinux $(obj)/fdimage ; sync
100 echo '$(image_cmdline)' | \
101 MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
102 if [ -f '$(FDINITRD)' ] ; then \
103 MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
104 fi
105 MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync
106
107isoimage: $(BOOTIMAGE)
108 -rm -rf $(obj)/isoimage
109 mkdir $(obj)/isoimage
110 for i in lib lib64 share end ; do \
111 if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
112 cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
113 break ; \
114 fi ; \
115 if [ $$i = end ] ; then exit 1 ; fi ; \
116 done
117 cp $(BOOTIMAGE) $(obj)/isoimage/linux
118 echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
119 if [ -f '$(FDINITRD)' ] ; then \
120 cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
121 fi
122 mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
123 -no-emul-boot -boot-load-size 4 -boot-info-table \
124 $(obj)/isoimage
125 rm -rf $(obj)/isoimage
126
127zlilo: $(BOOTIMAGE)
128 if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
129 if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
130 cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
131 cp System.map $(INSTALL_PATH)/
132 if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
133 7
134install: 8src := arch/i386/boot
135 sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" 9include $(src)/Makefile
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
deleted file mode 100644
index 011b7a4993d4..000000000000
--- a/arch/x86_64/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
3 *
4 * modified by Drew Eckhardt
5 * modified by Bruce Evans (bde)
6 * modified by Chris Noe (May 1999) (as86 -> gas)
7 * gutted by H. Peter Anvin (Jan 2003)
8 *
9 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
10 * addresses must be multiplied by 16 to obtain their respective linear
11 * addresses. To avoid confusion, linear addresses are written using leading
12 * hex while segment addresses are written as segment:offset.
13 *
14 */
15
16#include <asm/boot.h>
17
18SETUPSECTS = 4 /* default nr of setup-sectors */
19BOOTSEG = 0x07C0 /* original address of boot-sector */
20INITSEG = DEF_INITSEG /* we move boot here - out of the way */
21SETUPSEG = DEF_SETUPSEG /* setup starts here */
22SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
23SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
24 /* to be loaded */
25ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
26SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
27
28#ifndef SVGA_MODE
29#define SVGA_MODE ASK_VGA
30#endif
31
32#ifndef RAMDISK
33#define RAMDISK 0
34#endif
35
36#ifndef ROOT_RDONLY
37#define ROOT_RDONLY 1
38#endif
39
40.code16
41.text
42
43.global _start
44_start:
45
46 # Normalize the start address
47 jmpl $BOOTSEG, $start2
48
49start2:
50 movw %cs, %ax
51 movw %ax, %ds
52 movw %ax, %es
53 movw %ax, %ss
54 movw $0x7c00, %sp
55 sti
56 cld
57
58 movw $bugger_off_msg, %si
59
60msg_loop:
61 lodsb
62 andb %al, %al
63 jz die
64 movb $0xe, %ah
65 movw $7, %bx
66 int $0x10
67 jmp msg_loop
68
69die:
70 # Allow the user to press a key, then reboot
71 xorw %ax, %ax
72 int $0x16
73 int $0x19
74
75 # int 0x19 should never return. In case it does anyway,
76 # invoke the BIOS reset code...
77 ljmp $0xf000,$0xfff0
78
79
80bugger_off_msg:
81 .ascii "Direct booting from floppy is no longer supported.\r\n"
82 .ascii "Please use a boot loader program instead.\r\n"
83 .ascii "\n"
84 .ascii "Remove disk and press any key to reboot . . .\r\n"
85 .byte 0
86
87
88 # Kernel attributes; used by setup
89
90 .org 497
91setup_sects: .byte SETUPSECTS
92root_flags: .word ROOT_RDONLY
93syssize: .word SYSSIZE
94swap_dev: .word SWAP_DEV
95ram_size: .word RAMDISK
96vid_mode: .word SVGA_MODE
97root_dev: .word ROOT_DEV
98boot_flag: .word 0xAA55
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile
index 705a3e33d7e1..c9f2da7496c1 100644
--- a/arch/x86_64/boot/compressed/Makefile
+++ b/arch/x86_64/boot/compressed/Makefile
@@ -7,11 +7,12 @@
7# 7#
8 8
9targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o 9targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
10EXTRA_AFLAGS := -traditional
11 10
12# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with 11CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
13# -m32 12 -fno-strict-aliasing -fPIC -mcmodel=small \
14CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin 13 $(call cc-option, -ffreestanding) \
14 $(call cc-option, -fno-stack-protector)
15AFLAGS := $(CFLAGS) -D__ASSEMBLY__
15LDFLAGS := -m elf_x86_64 16LDFLAGS := -m elf_x86_64
16 17
17LDFLAGS_vmlinux := -T 18LDFLAGS_vmlinux := -T
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S
index f9d5692a0106..1312bfaff306 100644
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86_64/boot/compressed/head.S
@@ -46,10 +46,10 @@ startup_32:
46 * at and where we were actually loaded at. This can only be done 46 * at and where we were actually loaded at. This can only be done
47 * with a short local call on x86. Nothing else will tell us what 47 * with a short local call on x86. Nothing else will tell us what
48 * address we are running at. The reserved chunk of the real-mode 48 * address we are running at. The reserved chunk of the real-mode
49 * data at 0x34-0x3f are used as the stack for this calculation. 49 * data at 0x1e4 (defined as a scratch field) are used as the stack
50 * Only 4 bytes are needed. 50 * for this calculation. Only 4 bytes are needed.
51 */ 51 */
52 leal 0x40(%esi), %esp 52 leal (0x1e4+4)(%esi), %esp
53 call 1f 53 call 1f
541: popl %ebp 541: popl %ebp
55 subl $1b, %ebp 55 subl $1b, %ebp
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
deleted file mode 100644
index baaa2369bdb8..000000000000
--- a/arch/x86_64/boot/install.sh
+++ /dev/null
@@ -1,2 +0,0 @@
1#!/bin/sh
2. $srctree/arch/i386/boot/install.sh
diff --git a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in
deleted file mode 100644
index efd6d2490c1d..000000000000
--- a/arch/x86_64/boot/mtools.conf.in
+++ /dev/null
@@ -1,17 +0,0 @@
1#
2# mtools configuration file for "make (b)zdisk"
3#
4
5# Actual floppy drive
6drive a:
7 file="/dev/fd0"
8
9# 1.44 MB floppy disk image
10drive v:
11 file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
12
13# 2.88 MB floppy disk image (mostly for virtual uses)
14drive w:
15 file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
16
17
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
deleted file mode 100644
index e9e33f949697..000000000000
--- a/arch/x86_64/boot/setup.S
+++ /dev/null
@@ -1,826 +0,0 @@
1/*
2 * setup.S Copyright (C) 1991, 1992 Linus Torvalds
3 *
4 * setup.s is responsible for getting the system data from the BIOS,
5 * and putting them into the appropriate places in system memory.
6 * both setup.s and system has been loaded by the bootblock.
7 *
8 * This code asks the bios for memory/disk/other parameters, and
9 * puts them in a "safe" place: 0x90000-0x901FF, ie where the
10 * boot-block used to be. It is then up to the protected mode
11 * system to read them from there before the area is overwritten
12 * for buffer-blocks.
13 *
14 * Move PS/2 aux init code to psaux.c
15 * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
16 *
17 * some changes and additional features by Christoph Niemann,
18 * March 1993/June 1994 (Christoph.Niemann@linux.org)
19 *
20 * add APM BIOS checking by Stephen Rothwell, May 1994
21 * (sfr@canb.auug.org.au)
22 *
23 * High load stuff, initrd support and position independency
24 * by Hans Lermen & Werner Almesberger, February 1996
25 * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
26 *
27 * Video handling moved to video.S by Martin Mares, March 1996
28 * <mj@k332.feld.cvut.cz>
29 *
30 * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
31 * parsons) to avoid loadlin confusion, July 1997
32 *
33 * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
34 * <stiker@northlink.com>
35 *
36 * Fix to work around buggy BIOSes which don't use carry bit correctly
37 * and/or report extended memory in CX/DX for e801h memory size detection
38 * call. As a result the kernel got wrong figures. The int15/e801h docs
39 * from Ralf Brown interrupt list seem to indicate AX/BX should be used
40 * anyway. So to avoid breaking many machines (presumably there was a reason
41 * to orginally use CX/DX instead of AX/BX), we do a kludge to see
42 * if CX/DX have been changed in the e801 call and if so use AX/BX .
43 * Michael Miller, April 2001 <michaelm@mjmm.org>
44 *
45 * Added long mode checking and SSE force. March 2003, Andi Kleen.
46 */
47
48#include <asm/segment.h>
49#include <linux/utsrelease.h>
50#include <linux/compile.h>
51#include <asm/boot.h>
52#include <asm/e820.h>
53#include <asm/page.h>
54#include <asm/setup.h>
55
56/* Signature words to ensure LILO loaded us right */
57#define SIG1 0xAA55
58#define SIG2 0x5A5A
59
60INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way
61SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536).
62SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment
63 # ... and the former contents of CS
64
65DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020
66
67.code16
68.globl begtext, begdata, begbss, endtext, enddata, endbss
69
70.text
71begtext:
72.data
73begdata:
74.bss
75begbss:
76.text
77
78start:
79 jmp trampoline
80
81# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
82
83 .ascii "HdrS" # header signature
84 .word 0x0206 # header version number (>= 0x0105)
85 # or else old loadlin-1.5 will fail)
86realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
87start_sys_seg: .word SYSSEG
88 .word kernel_version # pointing to kernel version string
89 # above section of header is compatible
90 # with loadlin-1.5 (header v1.5). Don't
91 # change it.
92
93type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
94 # Bootlin, SYSLX, bootsect...)
95 # See Documentation/i386/boot.txt for
96 # assigned ids
97
98# flags, unused bits must be zero (RFU) bit within loadflags
99loadflags:
100LOADED_HIGH = 1 # If set, the kernel is loaded high
101CAN_USE_HEAP = 0x80 # If set, the loader also has set
102 # heap_end_ptr to tell how much
103 # space behind setup.S can be used for
104 # heap purposes.
105 # Only the loader knows what is free
106#ifndef __BIG_KERNEL__
107 .byte 0
108#else
109 .byte LOADED_HIGH
110#endif
111
112setup_move_size: .word 0x8000 # size to move, when setup is not
113 # loaded at 0x90000. We will move setup
114 # to 0x90000 then just before jumping
115 # into the kernel. However, only the
116 # loader knows how much data behind
117 # us also needs to be loaded.
118
119code32_start: # here loaders can put a different
120 # start address for 32-bit code.
121#ifndef __BIG_KERNEL__
122 .long 0x1000 # 0x1000 = default for zImage
123#else
124 .long 0x100000 # 0x100000 = default for big kernel
125#endif
126
127ramdisk_image: .long 0 # address of loaded ramdisk image
128 # Here the loader puts the 32-bit
129 # address where it loaded the image.
130 # This only will be read by the kernel.
131
132ramdisk_size: .long 0 # its size in bytes
133
134bootsect_kludge:
135 .long 0 # obsolete
136
137heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later)
138 # space from here (exclusive) down to
139 # end of setup code can be used by setup
140 # for local heap purposes.
141
142pad1: .word 0
143cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
144 # If nonzero, a 32-bit pointer
145 # to the kernel command line.
146 # The command line should be
147 # located between the start of
148 # setup and the end of low
149 # memory (0xa0000), or it may
150 # get overwritten before it
151 # gets read. If this field is
152 # used, there is no longer
153 # anything magical about the
154 # 0x90000 segment; the setup
155 # can be located anywhere in
156 # low memory 0x10000 or higher.
157
158ramdisk_max: .long 0xffffffff
159kernel_alignment: .long 0x200000 # physical addr alignment required for
160 # protected mode relocatable kernel
161#ifdef CONFIG_RELOCATABLE
162relocatable_kernel: .byte 1
163#else
164relocatable_kernel: .byte 0
165#endif
166pad2: .byte 0
167pad3: .word 0
168
169cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
170 #added with boot protocol
171 #version 2.06
172
173trampoline: call start_of_setup
174 .align 16
175 # The offset at this point is 0x240
176 .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
177# End of setup header #####################################################
178
179start_of_setup:
180# Bootlin depends on this being done early
181 movw $0x01500, %ax
182 movb $0x81, %dl
183 int $0x13
184
185#ifdef SAFE_RESET_DISK_CONTROLLER
186# Reset the disk controller.
187 movw $0x0000, %ax
188 movb $0x80, %dl
189 int $0x13
190#endif
191
192# Set %ds = %cs, we know that SETUPSEG = %cs at this point
193 movw %cs, %ax # aka SETUPSEG
194 movw %ax, %ds
195# Check signature at end of setup
196 cmpw $SIG1, setup_sig1
197 jne bad_sig
198
199 cmpw $SIG2, setup_sig2
200 jne bad_sig
201
202 jmp good_sig1
203
204# Routine to print asciiz string at ds:si
205prtstr:
206 lodsb
207 andb %al, %al
208 jz fin
209
210 call prtchr
211 jmp prtstr
212
213fin: ret
214
215# Space printing
216prtsp2: call prtspc # Print double space
217prtspc: movb $0x20, %al # Print single space (note: fall-thru)
218
219prtchr:
220 pushw %ax
221 pushw %cx
222 movw $0007,%bx
223 movw $0x01, %cx
224 movb $0x0e, %ah
225 int $0x10
226 popw %cx
227 popw %ax
228 ret
229
230beep: movb $0x07, %al
231 jmp prtchr
232
233no_sig_mess: .string "No setup signature found ..."
234
235good_sig1:
236 jmp good_sig
237
238# We now have to find the rest of the setup code/data
239bad_sig:
240 movw %cs, %ax # SETUPSEG
241 subw $DELTA_INITSEG, %ax # INITSEG
242 movw %ax, %ds
243 xorb %bh, %bh
244 movb (497), %bl # get setup sect from bootsect
245 subw $4, %bx # LILO loads 4 sectors of setup
246 shlw $8, %bx # convert to words (1sect=2^8 words)
247 movw %bx, %cx
248 shrw $3, %bx # convert to segment
249 addw $SYSSEG, %bx
250 movw %bx, %cs:start_sys_seg
251# Move rest of setup code/data to here
252 movw $2048, %di # four sectors loaded by LILO
253 subw %si, %si
254 movw %cs, %ax # aka SETUPSEG
255 movw %ax, %es
256 movw $SYSSEG, %ax
257 movw %ax, %ds
258 rep
259 movsw
260 movw %cs, %ax # aka SETUPSEG
261 movw %ax, %ds
262 cmpw $SIG1, setup_sig1
263 jne no_sig
264
265 cmpw $SIG2, setup_sig2
266 jne no_sig
267
268 jmp good_sig
269
270no_sig:
271 lea no_sig_mess, %si
272 call prtstr
273
274no_sig_loop:
275 jmp no_sig_loop
276
277good_sig:
278 movw %cs, %ax # aka SETUPSEG
279 subw $DELTA_INITSEG, %ax # aka INITSEG
280 movw %ax, %ds
281# Check if an old loader tries to load a big-kernel
282 testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel?
283 jz loader_ok # No, no danger for old loaders.
284
285 cmpb $0, %cs:type_of_loader # Do we have a loader that
286 # can deal with us?
287 jnz loader_ok # Yes, continue.
288
289 pushw %cs # No, we have an old loader,
290 popw %ds # die.
291 lea loader_panic_mess, %si
292 call prtstr
293
294 jmp no_sig_loop
295
296loader_panic_mess: .string "Wrong loader, giving up..."
297
298loader_ok:
299 /* check for long mode. */
300 /* we have to do this before the VESA setup, otherwise the user
301 can't see the error message. */
302
303 pushw %ds
304 movw %cs,%ax
305 movw %ax,%ds
306
307 call verify_cpu
308 testl %eax,%eax
309 jz sse_ok
310
311no_longmode:
312 call beep
313 lea long_mode_panic,%si
314 call prtstr
315no_longmode_loop:
316 jmp no_longmode_loop
317long_mode_panic:
318 .string "Your CPU does not support long mode. Use a 32bit distribution."
319 .byte 0
320
321#include "../kernel/verify_cpu.S"
322sse_ok:
323 popw %ds
324
325# tell BIOS we want to go to long mode
326 movl $0xec00,%eax # declare target operating mode
327 movl $2,%ebx # long mode
328 int $0x15
329
330# Get memory size (extended mem, kB)
331
332 xorl %eax, %eax
333 movl %eax, (0x1e0)
334#ifndef STANDARD_MEMORY_BIOS_CALL
335 movb %al, (E820NR)
336# Try three different memory detection schemes. First, try
337# e820h, which lets us assemble a memory map, then try e801h,
338# which returns a 32-bit memory size, and finally 88h, which
339# returns 0-64m
340
341# method E820H:
342# the memory map from hell. e820h returns memory classified into
343# a whole bunch of different types, and allows memory holes and
344# everything. We scan through this memory map and build a list
345# of the first 32 memory areas, which we return at [E820MAP].
346# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
347
348#define SMAP 0x534d4150
349
350meme820:
351 xorl %ebx, %ebx # continuation counter
352 movw $E820MAP, %di # point into the whitelist
353 # so we can have the bios
354 # directly write into it.
355
356jmpe820:
357 movl $0x0000e820, %eax # e820, upper word zeroed
358 movl $SMAP, %edx # ascii 'SMAP'
359 movl $20, %ecx # size of the e820rec
360 pushw %ds # data record.
361 popw %es
362 int $0x15 # make the call
363 jc bail820 # fall to e801 if it fails
364
365 cmpl $SMAP, %eax # check the return is `SMAP'
366 jne bail820 # fall to e801 if it fails
367
368# cmpl $1, 16(%di) # is this usable memory?
369# jne again820
370
371 # If this is usable memory, we save it by simply advancing %di by
372 # sizeof(e820rec).
373 #
374good820:
375 movb (E820NR), %al # up to 128 entries
376 cmpb $E820MAX, %al
377 jae bail820
378
379 incb (E820NR)
380 movw %di, %ax
381 addw $20, %ax
382 movw %ax, %di
383again820:
384 cmpl $0, %ebx # check to see if
385 jne jmpe820 # %ebx is set to EOF
386bail820:
387
388
389# method E801H:
390# memory size is in 1k chunksizes, to avoid confusing loadlin.
391# we store the 0xe801 memory size in a completely different place,
392# because it will most likely be longer than 16 bits.
393# (use 1e0 because that's what Larry Augustine uses in his
394# alternative new memory detection scheme, and it's sensible
395# to write everything into the same place.)
396
397meme801:
398 stc # fix to work around buggy
399 xorw %cx,%cx # BIOSes which don't clear/set
400 xorw %dx,%dx # carry on pass/error of
401 # e801h memory size call
402 # or merely pass cx,dx though
403 # without changing them.
404 movw $0xe801, %ax
405 int $0x15
406 jc mem88
407
408 cmpw $0x0, %cx # Kludge to handle BIOSes
409 jne e801usecxdx # which report their extended
410 cmpw $0x0, %dx # memory in AX/BX rather than
411 jne e801usecxdx # CX/DX. The spec I have read
412 movw %ax, %cx # seems to indicate AX/BX
413 movw %bx, %dx # are more reasonable anyway...
414
415e801usecxdx:
416 andl $0xffff, %edx # clear sign extend
417 shll $6, %edx # and go from 64k to 1k chunks
418 movl %edx, (0x1e0) # store extended memory size
419 andl $0xffff, %ecx # clear sign extend
420 addl %ecx, (0x1e0) # and add lower memory into
421 # total size.
422
423# Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
424# 64mb, depending on the bios) in ax.
425mem88:
426
427#endif
428 movb $0x88, %ah
429 int $0x15
430 movw %ax, (2)
431
432# Set the keyboard repeat rate to the max
433 movw $0x0305, %ax
434 xorw %bx, %bx
435 int $0x16
436
437# Check for video adapter and its parameters and allow the
438# user to browse video modes.
439 call video # NOTE: we need %ds pointing
440 # to bootsector
441
442# Get hd0 data...
443 xorw %ax, %ax
444 movw %ax, %ds
445 ldsw (4 * 0x41), %si
446 movw %cs, %ax # aka SETUPSEG
447 subw $DELTA_INITSEG, %ax # aka INITSEG
448 pushw %ax
449 movw %ax, %es
450 movw $0x0080, %di
451 movw $0x10, %cx
452 pushw %cx
453 cld
454 rep
455 movsb
456# Get hd1 data...
457 xorw %ax, %ax
458 movw %ax, %ds
459 ldsw (4 * 0x46), %si
460 popw %cx
461 popw %es
462 movw $0x0090, %di
463 rep
464 movsb
465# Check that there IS a hd1 :-)
466 movw $0x01500, %ax
467 movb $0x81, %dl
468 int $0x13
469 jc no_disk1
470
471 cmpb $3, %ah
472 je is_disk1
473
474no_disk1:
475 movw %cs, %ax # aka SETUPSEG
476 subw $DELTA_INITSEG, %ax # aka INITSEG
477 movw %ax, %es
478 movw $0x0090, %di
479 movw $0x10, %cx
480 xorw %ax, %ax
481 cld
482 rep
483 stosb
484is_disk1:
485
486# Check for PS/2 pointing device
487 movw %cs, %ax # aka SETUPSEG
488 subw $DELTA_INITSEG, %ax # aka INITSEG
489 movw %ax, %ds
490 movb $0, (0x1ff) # default is no pointing device
491 int $0x11 # int 0x11: equipment list
492 testb $0x04, %al # check if mouse installed
493 jz no_psmouse
494
495 movb $0xAA, (0x1ff) # device present
496no_psmouse:
497
498#include "../../i386/boot/edd.S"
499
500# Now we want to move to protected mode ...
501 cmpw $0, %cs:realmode_swtch
502 jz rmodeswtch_normal
503
504 lcall *%cs:realmode_swtch
505
506 jmp rmodeswtch_end
507
508rmodeswtch_normal:
509 pushw %cs
510 call default_switch
511
512rmodeswtch_end:
513# we get the code32 start address and modify the below 'jmpi'
514# (loader may have changed it)
515 movl %cs:code32_start, %eax
516 movl %eax, %cs:code32
517
518# Now we move the system to its rightful place ... but we check if we have a
519# big-kernel. In that case we *must* not move it ...
520 testb $LOADED_HIGH, %cs:loadflags
521 jz do_move0 # .. then we have a normal low
522 # loaded zImage
523 # .. or else we have a high
524 # loaded bzImage
525 jmp end_move # ... and we skip moving
526
527do_move0:
528 movw $0x100, %ax # start of destination segment
529 movw %cs, %bp # aka SETUPSEG
530 subw $DELTA_INITSEG, %bp # aka INITSEG
531 movw %cs:start_sys_seg, %bx # start of source segment
532 cld
533do_move:
534 movw %ax, %es # destination segment
535 incb %ah # instead of add ax,#0x100
536 movw %bx, %ds # source segment
537 addw $0x100, %bx
538 subw %di, %di
539 subw %si, %si
540 movw $0x800, %cx
541 rep
542 movsw
543 cmpw %bp, %bx # assume start_sys_seg > 0x200,
544 # so we will perhaps read one
545 # page more than needed, but
546 # never overwrite INITSEG
547 # because destination is a
548 # minimum one page below source
549 jb do_move
550
551end_move:
552# then we load the segment descriptors
553 movw %cs, %ax # aka SETUPSEG
554 movw %ax, %ds
555
556# Check whether we need to be downward compatible with version <=201
557 cmpl $0, cmd_line_ptr
558 jne end_move_self # loader uses version >=202 features
559 cmpb $0x20, type_of_loader
560 je end_move_self # bootsect loader, we know of it
561
562# Boot loader doesnt support boot protocol version 2.02.
563# If we have our code not at 0x90000, we need to move it there now.
564# We also then need to move the params behind it (commandline)
565# Because we would overwrite the code on the current IP, we move
566# it in two steps, jumping high after the first one.
567 movw %cs, %ax
568 cmpw $SETUPSEG, %ax
569 je end_move_self
570
571 cli # make sure we really have
572 # interrupts disabled !
573 # because after this the stack
574 # should not be used
575 subw $DELTA_INITSEG, %ax # aka INITSEG
576 movw %ss, %dx
577 cmpw %ax, %dx
578 jb move_self_1
579
580 addw $INITSEG, %dx
581 subw %ax, %dx # this will go into %ss after
582 # the move
583move_self_1:
584 movw %ax, %ds
585 movw $INITSEG, %ax # real INITSEG
586 movw %ax, %es
587 movw %cs:setup_move_size, %cx
588 std # we have to move up, so we use
589 # direction down because the
590 # areas may overlap
591 movw %cx, %di
592 decw %di
593 movw %di, %si
594 subw $move_self_here+0x200, %cx
595 rep
596 movsb
597 ljmp $SETUPSEG, $move_self_here
598
599move_self_here:
600 movw $move_self_here+0x200, %cx
601 rep
602 movsb
603 movw $SETUPSEG, %ax
604 movw %ax, %ds
605 movw %dx, %ss
606end_move_self: # now we are at the right place
607 lidt idt_48 # load idt with 0,0
608 xorl %eax, %eax # Compute gdt_base
609 movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
610 shll $4, %eax
611 addl $gdt, %eax
612 movl %eax, (gdt_48+2)
613 lgdt gdt_48 # load gdt with whatever is
614 # appropriate
615
616# that was painless, now we enable a20
617 call empty_8042
618
619 movb $0xD1, %al # command write
620 outb %al, $0x64
621 call empty_8042
622
623 movb $0xDF, %al # A20 on
624 outb %al, $0x60
625 call empty_8042
626
627#
628# You must preserve the other bits here. Otherwise embarrasing things
629# like laptops powering off on boot happen. Corrected version by Kira
630# Brown from Linux 2.2
631#
632 inb $0x92, %al #
633 orb $02, %al # "fast A20" version
634 outb %al, $0x92 # some chips have only this
635
636# wait until a20 really *is* enabled; it can take a fair amount of
637# time on certain systems; Toshiba Tecras are known to have this
638# problem. The memory location used here (0x200) is the int 0x80
639# vector, which should be safe to use.
640
641 xorw %ax, %ax # segment 0x0000
642 movw %ax, %fs
643 decw %ax # segment 0xffff (HMA)
644 movw %ax, %gs
645a20_wait:
646 incw %ax # unused memory location <0xfff0
647 movw %ax, %fs:(0x200) # we use the "int 0x80" vector
648 cmpw %gs:(0x210), %ax # and its corresponding HMA addr
649 je a20_wait # loop until no longer aliased
650
651# make sure any possible coprocessor is properly reset..
652 xorw %ax, %ax
653 outb %al, $0xf0
654 call delay
655
656 outb %al, $0xf1
657 call delay
658
659# well, that went ok, I hope. Now we mask all interrupts - the rest
660# is done in init_IRQ().
661 movb $0xFF, %al # mask all interrupts for now
662 outb %al, $0xA1
663 call delay
664
665 movb $0xFB, %al # mask all irq's but irq2 which
666 outb %al, $0x21 # is cascaded
667
668# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
669# need no steenking BIOS anyway (except for the initial loading :-).
670# The BIOS-routine wants lots of unnecessary data, and it's less
671# "interesting" anyway. This is how REAL programmers do it.
672#
673# Well, now's the time to actually move into protected mode. To make
674# things as simple as possible, we do no register set-up or anything,
675# we let the gnu-compiled 32-bit programs do that. We just jump to
676# absolute address 0x1000 (or the loader supplied one),
677# in 32-bit protected mode.
678#
679# Note that the short jump isn't strictly needed, although there are
680# reasons why it might be a good idea. It won't hurt in any case.
681 movw $1, %ax # protected mode (PE) bit
682 lmsw %ax # This is it!
683 jmp flush_instr
684
685flush_instr:
686 xorw %bx, %bx # Flag to indicate a boot
687 xorl %esi, %esi # Pointer to real-mode code
688 movw %cs, %si
689 subw $DELTA_INITSEG, %si
690 shll $4, %esi # Convert to 32-bit pointer
691# NOTE: For high loaded big kernels we need a
692# jmpi 0x100000,__KERNEL_CS
693#
694# but we yet haven't reloaded the CS register, so the default size
695# of the target offset still is 16 bit.
696# However, using an operand prefix (0x66), the CPU will properly
697# take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
698# Manual, Mixing 16-bit and 32-bit code, page 16-6)
699
700 .byte 0x66, 0xea # prefix + jmpi-opcode
701code32: .long 0x1000 # will be set to 0x100000
702 # for big kernels
703 .word __KERNEL_CS
704
705# Here's a bunch of information about your current kernel..
706kernel_version: .ascii UTS_RELEASE
707 .ascii " ("
708 .ascii LINUX_COMPILE_BY
709 .ascii "@"
710 .ascii LINUX_COMPILE_HOST
711 .ascii ") "
712 .ascii UTS_VERSION
713 .byte 0
714
715# This is the default real mode switch routine.
716# to be called just before protected mode transition
717default_switch:
718 cli # no interrupts allowed !
719 movb $0x80, %al # disable NMI for bootup
720 # sequence
721 outb %al, $0x70
722 lret
723
724
725# This routine checks that the keyboard command queue is empty
726# (after emptying the output buffers)
727#
728# Some machines have delusions that the keyboard buffer is always full
729# with no keyboard attached...
730#
731# If there is no keyboard controller, we will usually get 0xff
732# to all the reads. With each IO taking a microsecond and
733# a timeout of 100,000 iterations, this can take about half a
734# second ("delay" == outb to port 0x80). That should be ok,
735# and should also be plenty of time for a real keyboard controller
736# to empty.
737#
738
739empty_8042:
740 pushl %ecx
741 movl $100000, %ecx
742
743empty_8042_loop:
744 decl %ecx
745 jz empty_8042_end_loop
746
747 call delay
748
749 inb $0x64, %al # 8042 status port
750 testb $1, %al # output buffer?
751 jz no_output
752
753 call delay
754 inb $0x60, %al # read it
755 jmp empty_8042_loop
756
757no_output:
758 testb $2, %al # is input buffer full?
759 jnz empty_8042_loop # yes - loop
760empty_8042_end_loop:
761 popl %ecx
762 ret
763
764# Read the cmos clock. Return the seconds in al
765gettime:
766 pushw %cx
767 movb $0x02, %ah
768 int $0x1a
769 movb %dh, %al # %dh contains the seconds
770 andb $0x0f, %al
771 movb %dh, %ah
772 movb $0x04, %cl
773 shrb %cl, %ah
774 aad
775 popw %cx
776 ret
777
778# Delay is needed after doing I/O
779delay:
780 outb %al,$0x80
781 ret
782
783# Descriptor tables
784gdt:
785 .word 0, 0, 0, 0 # dummy
786
787 .word 0, 0, 0, 0 # unused
788
789 .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
790 .word 0 # base address = 0
791 .word 0x9A00 # code read/exec
792 .word 0x00CF # granularity = 4096, 386
793 # (+5th nibble of limit)
794
795 .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
796 .word 0 # base address = 0
797 .word 0x9200 # data read/write
798 .word 0x00CF # granularity = 4096, 386
799 # (+5th nibble of limit)
800gdt_end:
801idt_48:
802 .word 0 # idt limit = 0
803 .word 0, 0 # idt base = 0L
804gdt_48:
805 .word gdt_end-gdt-1 # gdt limit
806 .word 0, 0 # gdt base (filled in later)
807
808# Include video setup & detection code
809
810#include "../../i386/boot/video.S"
811
812# Setup signature -- must be last
813setup_sig1: .word SIG1
814setup_sig2: .word SIG2
815
816# After this point, there is some free space which is used by the video mode
817# handling code to store the temporary mode table (not used by the kernel).
818
819modelist:
820
821.text
822endtext:
823.data
824enddata:
825.bss
826endbss:
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
deleted file mode 100644
index eae86691709a..000000000000
--- a/arch/x86_64/boot/tools/build.c
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 1997 Martin Mares
4 */
5
6/*
7 * This file builds a disk-image from three different files:
8 *
9 * - bootsect: compatibility mbr which prints an error message if
10 * someone tries to boot the kernel directly.
11 * - setup: 8086 machine code, sets up system parm
12 * - system: 80386 code for actual system
13 *
14 * It does some checking that all files are of the correct type, and
15 * just writes the result to stdout, removing headers and padding to
16 * the right amount. It also writes some system data to stderr.
17 */
18
19/*
20 * Changes by tytso to allow root device specification
21 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
22 * Cross compiling fixes by Gertjan van Wingerde, July 1996
23 * Rewritten by Martin Mares, April 1997
24 */
25
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include <stdarg.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <sys/sysmacros.h>
33#include <unistd.h>
34#include <fcntl.h>
35#include <asm/boot.h>
36
37typedef unsigned char byte;
38typedef unsigned short word;
39typedef unsigned long u32;
40
41#define DEFAULT_MAJOR_ROOT 0
42#define DEFAULT_MINOR_ROOT 0
43
44/* Minimal number of setup sectors (see also bootsect.S) */
45#define SETUP_SECTS 4
46
47byte buf[1024];
48int fd;
49int is_big_kernel;
50
51void die(const char * str, ...)
52{
53 va_list args;
54 va_start(args, str);
55 vfprintf(stderr, str, args);
56 fputc('\n', stderr);
57 exit(1);
58}
59
60void file_open(const char *name)
61{
62 if ((fd = open(name, O_RDONLY, 0)) < 0)
63 die("Unable to open `%s': %m", name);
64}
65
66void usage(void)
67{
68 die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
69}
70
71int main(int argc, char ** argv)
72{
73 unsigned int i, c, sz, setup_sectors;
74 u32 sys_size;
75 byte major_root, minor_root;
76 struct stat sb;
77
78 if (argc > 2 && !strcmp(argv[1], "-b"))
79 {
80 is_big_kernel = 1;
81 argc--, argv++;
82 }
83 if ((argc < 4) || (argc > 5))
84 usage();
85 if (argc > 4) {
86 if (!strcmp(argv[4], "CURRENT")) {
87 if (stat("/", &sb)) {
88 perror("/");
89 die("Couldn't stat /");
90 }
91 major_root = major(sb.st_dev);
92 minor_root = minor(sb.st_dev);
93 } else if (strcmp(argv[4], "FLOPPY")) {
94 if (stat(argv[4], &sb)) {
95 perror(argv[4]);
96 die("Couldn't stat root device.");
97 }
98 major_root = major(sb.st_rdev);
99 minor_root = minor(sb.st_rdev);
100 } else {
101 major_root = 0;
102 minor_root = 0;
103 }
104 } else {
105 major_root = DEFAULT_MAJOR_ROOT;
106 minor_root = DEFAULT_MINOR_ROOT;
107 }
108 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
109
110 file_open(argv[1]);
111 i = read(fd, buf, sizeof(buf));
112 fprintf(stderr,"Boot sector %d bytes.\n",i);
113 if (i != 512)
114 die("Boot block must be exactly 512 bytes");
115 if (buf[510] != 0x55 || buf[511] != 0xaa)
116 die("Boot block hasn't got boot flag (0xAA55)");
117 buf[508] = minor_root;
118 buf[509] = major_root;
119 if (write(1, buf, 512) != 512)
120 die("Write call failed");
121 close (fd);
122
123 file_open(argv[2]); /* Copy the setup code */
124 for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
125 if (write(1, buf, c) != c)
126 die("Write call failed");
127 if (c != 0)
128 die("read-error on `setup'");
129 close (fd);
130
131 setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */
132 /* for compatibility with ancient versions of LILO. */
133 if (setup_sectors < SETUP_SECTS)
134 setup_sectors = SETUP_SECTS;
135 fprintf(stderr, "Setup is %d bytes.\n", i);
136 memset(buf, 0, sizeof(buf));
137 while (i < setup_sectors * 512) {
138 c = setup_sectors * 512 - i;
139 if (c > sizeof(buf))
140 c = sizeof(buf);
141 if (write(1, buf, c) != c)
142 die("Write call failed");
143 i += c;
144 }
145
146 file_open(argv[3]);
147 if (fstat (fd, &sb))
148 die("Unable to stat `%s': %m", argv[3]);
149 sz = sb.st_size;
150 fprintf (stderr, "System is %d kB\n", sz/1024);
151 sys_size = (sz + 15) / 16;
152 if (!is_big_kernel && sys_size > DEF_SYSSIZE)
153 die("System is too big. Try using bzImage or modules.");
154 while (sz > 0) {
155 int l, n;
156
157 l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
158 if ((n=read(fd, buf, l)) != l) {
159 if (n < 0)
160 die("Error reading %s: %m", argv[3]);
161 else
162 die("%s: Unexpected EOF", argv[3]);
163 }
164 if (write(1, buf, l) != l)
165 die("Write failed");
166 sz -= l;
167 }
168 close(fd);
169
170 if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */
171 die("Output: seek failed");
172 buf[0] = setup_sectors;
173 if (write(1, buf, 1) != 1)
174 die("Write of setup sector count failed");
175 if (lseek(1, 500, SEEK_SET) != 500)
176 die("Output: seek failed");
177 buf[0] = (sys_size & 0xff);
178 buf[1] = ((sys_size >> 8) & 0xff);
179 buf[2] = ((sys_size >> 16) & 0xff);
180 buf[3] = ((sys_size >> 24) & 0xff);
181 if (write(1, buf, 4) != 4)
182 die("Write of image length failed");
183
184 return 0; /* Everything is OK */
185}
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index de1de8a2fd84..47f1dc30bf56 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PCI) += early-quirks.o
44 44
45obj-y += topology.o 45obj-y += topology.o
46obj-y += intel_cacheinfo.o 46obj-y += intel_cacheinfo.o
47obj-y += addon_cpuid_features.o
47obj-y += pcspeaker.o 48obj-y += pcspeaker.o
48 49
49CFLAGS_vsyscall.o := $(PROFILING) -g0 50CFLAGS_vsyscall.o := $(PROFILING) -g0
@@ -55,6 +56,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
55topology-y += ../../i386/kernel/topology.o 56topology-y += ../../i386/kernel/topology.o
56microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o 57microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
57intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o 58intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
59addon_cpuid_features-y += ../../i386/kernel/cpu/addon_cpuid_features.o
58quirks-y += ../../i386/kernel/quirks.o 60quirks-y += ../../i386/kernel/quirks.o
59i8237-y += ../../i386/kernel/i8237.o 61i8237-y += ../../i386/kernel/i8237.o
60msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o 62msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index eb6524f3ac29..33ef718f8cb5 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -846,6 +846,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
846 c->x86_capability[2] = cpuid_edx(0x80860001); 846 c->x86_capability[2] = cpuid_edx(0x80860001);
847 } 847 }
848 848
849 init_scattered_cpuid_features(c);
850
849 c->apicid = phys_pkg_id(0); 851 c->apicid = phys_pkg_id(0);
850 852
851 /* 853 /*
@@ -931,7 +933,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
931 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", 933 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
932 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", 934 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
933 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", 935 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
934 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, 936 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
935 937
936 /* AMD-defined */ 938 /* AMD-defined */
937 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 939 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -947,10 +949,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
947 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 949 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
948 950
949 /* Other (Linux-defined) */ 951 /* Other (Linux-defined) */
950 "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, 952 "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
951 "constant_tsc", NULL, NULL, 953 NULL, NULL, NULL, NULL,
952 "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 954 "constant_tsc", "up", NULL, "arch_perfmon",
953 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 955 "pebs", "bts", NULL, "sync_rdtsc",
956 "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
954 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 957 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
955 958
956 /* Intel-defined (#2) */ 959 /* Intel-defined (#2) */
@@ -961,7 +964,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
961 964
962 /* VIA/Cyrix/Centaur-defined */ 965 /* VIA/Cyrix/Centaur-defined */
963 NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", 966 NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
964 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 967 "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
965 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 968 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
966 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 969 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
967 970
@@ -972,6 +975,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
972 "osvw", "ibs", NULL, NULL, NULL, NULL, 975 "osvw", "ibs", NULL, NULL, NULL, NULL,
973 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 976 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
974 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 977 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
978
979 /* Auxiliary (Linux-defined) */
980 "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
981 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
982 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
983 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
975 }; 984 };
976 static char *x86_power_flags[] = { 985 static char *x86_power_flags[] = {
977 "ts", /* temperature sensor */ 986 "ts", /* temperature sensor */
diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86_64/kernel/verify_cpu.S
index e035f5948199..45b6f8a975a1 100644
--- a/arch/x86_64/kernel/verify_cpu.S
+++ b/arch/x86_64/kernel/verify_cpu.S
@@ -37,20 +37,6 @@ verify_cpu:
37 pushl $0 # Kill any dangerous flags 37 pushl $0 # Kill any dangerous flags
38 popfl 38 popfl
39 39
40 /* minimum CPUID flags for x86-64 as defined by AMD */
41#define M(x) (1<<(x))
42#define M2(a,b) M(a)|M(b)
43#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
44
45#define SSE_MASK \
46 (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
47#define REQUIRED_MASK1 \
48 (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
49 M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
50 M(X86_FEATURE_FXSR))
51#define REQUIRED_MASK2 \
52 (M(X86_FEATURE_LM - 32))
53
54 pushfl # standard way to check for cpuid 40 pushfl # standard way to check for cpuid
55 popl %eax 41 popl %eax
56 movl %eax,%ebx 42 movl %eax,%ebx
@@ -79,8 +65,8 @@ verify_cpu:
79verify_cpu_noamd: 65verify_cpu_noamd:
80 movl $0x1,%eax # Does the cpu have what it takes 66 movl $0x1,%eax # Does the cpu have what it takes
81 cpuid 67 cpuid
82 andl $REQUIRED_MASK1,%edx 68 andl $REQUIRED_MASK0,%edx
83 xorl $REQUIRED_MASK1,%edx 69 xorl $REQUIRED_MASK0,%edx
84 jnz verify_cpu_no_longmode 70 jnz verify_cpu_no_longmode
85 71
86 movl $0x80000000,%eax # See if extended cpuid is implemented 72 movl $0x80000000,%eax # See if extended cpuid is implemented
@@ -90,8 +76,8 @@ verify_cpu_noamd:
90 76
91 movl $0x80000001,%eax # Does the cpu have what it takes 77 movl $0x80000001,%eax # Does the cpu have what it takes
92 cpuid 78 cpuid
93 andl $REQUIRED_MASK2,%edx 79 andl $REQUIRED_MASK1,%edx
94 xorl $REQUIRED_MASK2,%edx 80 xorl $REQUIRED_MASK1,%edx
95 jnz verify_cpu_no_longmode 81 jnz verify_cpu_no_longmode
96 82
97verify_cpu_sse_test: 83verify_cpu_sse_test: